Annotation of freem/doc/freem.texi, revision 1.37

1.1       snw         1: \input texinfo
                      2: @paragraphindent 0
                      3: @setfilename freem.info
                      4: @settitle The FreeM Manual
                      5: 
                      6: @copying
1.36      snw         7: This manual is for FreeM, (version 0.64.0-rc1), which is a free software@footnote{FreeM subscribes to the software licensing philosophy described in @emph{Free Software, Free Society:
                      8: Selected Essays of Richard M. Stallman}.} implementation of the M programming language.
1.1       snw         9: 
                     10: 
1.5       snw        11: Copyright @copyright{} 2014-2025 Coherent Logic Development LLC
1.1       snw        12: 
                     13: @quotation
                     14: Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover texts, and with no Back-Cover Texts.
                     15: @end quotation
                     16: @end copying
                     17: 
                     18: @titlepage
                     19: 
                     20: @title The FreeM Manual
                     21: @subtitle @sc{The Official Manual of FreeM}
1.32      snw        22: @subtitle Version 0.64.0-rc1
1.1       snw        23: @c@vskip 10pt
                     24: @c@center @image{freem-logo-sm,,,,.png}
                     25: @author Serena Willis
                     26: @page
                     27: @vskip 0pt plus 1filll
                     28: @insertcopying
                     29: @end titlepage
                     30: @contents
                     31: 
                     32: @ifnottex
                     33: @node Top
                     34: @top The FreeM Manual
                     35: 
                     36: This is the official manual for the FreeM programming language.
                     37: @end ifnottex
                     38: 
                     39: @dircategory The FreeM Manual
                     40: @direntry
                     41: * FreeM: (freem).                       The FreeM M programming language.
                     42: @end direntry
                     43: 
                     44: @menu
                     45: * Introduction::                        About the FreeM Project, its history, and its goals.
1.36      snw        46: * Document Conventions::                Conventions used in this manual.
1.1       snw        47: * FreeM Invocation::                    How to invoke FreeM from the command line.
1.22      snw        48: * The FreeM Environment Daemon::        Managing shared resources in the FreeM environment.
1.1       snw        49: * The FreeM Direct-Mode Environment::   Executing M programs interactively.
1.36      snw        50: * Debugging::                           The program development cycle of FreeM.
1.1       snw        51: 
                     52: * Directives::                          Per-Routine Language Directives.
                     53: * Intrinsic Special Variables::         Intrinsic Special Variables.
                     54: * Intrinsic Functions::                 Intrinsic Functions.
                     55: * OBJECT Methods::                      Methods for OBJECT variables.
                     56: * STRING Methods::                      Methods for STRING variables.
                     57: * Commands::                            Commands.
                     58: * Structured System Variables::         Structured System Variables.
                     59: * Operators::                           FreeM Operators.
                     60: 
                     61: * Routines::                            The units of M code in FreeM.
                     62: * Types::                               FreeM data types.
                     63: * Globals::                             FreeM persistent sparse arrays.
                     64: * Concurrency Control::                 @code{LOCK}ing and transaction processing.
                     65: * Local Variables::                     In-memory variables.
                     66: * Scoping::                             Scoping in FreeM.
                     67: * Decision Constructs::                 @code{IF}, @code{THEN}, @code{ELSE}, @code{$SELECT}, and postconditionals.
                     68: * Branch Constructs::                   Labels, @code{GOTO}, @code{DO}, and @code{JOB}.
                     69: * Loop Constructs::                     The @code{FOR} loop.
                     70: * Modular Programming::                 Extrinsic functions and subroutines.
                     71: * Object-Oriented Programming::         Classes and objects in FreeM.
                     72: * Libraries::                           System and user libraries.
                     73: * Sequential I/O::                      Processing sequential files in FreeM.
                     74: * Network I/O::                         Handling network sockets in FreeM.
                     75: * Extended Global References::          Accessing globals in non-default namespaces.
                     76: * Global Aliasing::                     Defining alternate names for globals.
                     77: * Global Mappings::                     Mapping global names to non-default namespaces.
                     78: 
                     79: * Asynchronous Event Handling::         Handling asynchronous events in FreeM.
                     80: * Global Triggers::                     Responding to global accesses in M code.
                     81: * Synchronous Event Handling::          Synchronous events in FreeM.
                     82: 
                     83: 
                     84: * GUI Programming with MWAPI::          Creating graphical interfaces in FreeM.
                     85: 
                     86: * User-Defined Z Commands::             Adding your own Z commands to FreeM.
                     87: * User-Defined Z Functions::            Adding your own Z functions to FreeM.
                     88: * User-Defined SSVNs::                  Adding your own SSVNs to FreeM.
                     89: 
                     90: * Language Dialects::                   Controlling FreeM standards compliance.
                     91: 
                     92: * System Library Routines::             FreeM built-in library of M routines.
                     93: 
                     94: * Interrupt Handling::                  How FreeM handles interrupts.
                     95: * Error Processing::                    How to handle errors in M program code.
                     96: * FreeM Error Codes::                   Explanations of each FreeM error code.
                     97: 
                     98: * System Configuration::                Configuring your FreeM installation.
                     99: * Accessing FreeM from C Programs::     How to use the mlib interface.
                    100: 
                    101: * FreeM Administrator::                 The fmadm system manager tool.
                    102: * FreeM Legacy Utilities::              FreeM legacy system manager utilities.
                    103: * FreeM VIEW Commands and Functions::   Getting and setting info about FreeM internals.
                    104: * Implementation Limits::               FreeM limitations.
                    105: * US-ASCII Character Set::              The US-ASCII character set.
                    106: * FreeM Project Coding Standards::      How to write code for submission to the FreeM project.
                    107: 
                    108: * Index::               Complete index.
                    109: @end menu
                    110: 
                    111: @node Introduction
                    112: @unnumbered Introduction
                    113: 
1.36      snw       114: FreeM started its life as @emph{FreeMUMPS}, written for MS-DOS and ported to SCO UNIX by a mysterious individual going by the name of "Shalom ha-Ashkenaz". It was released to MUG Deutschland in 1998. In 1999, Ronald L. Fox ported FreeM to the Red Hat Linux 5 distribution of the GNU/Linux operating system. Thereafter, maintenance was taken over by the Generic Universal M Project, which changed its name first to Public Standard MUMPS and then by popular request to FreeM.
1.1       snw       115: 
                    116: 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 Serena 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 @code{$VIEW} functions were added to retrieve the terminal size information. @code{$X} and @code{$Y} intrinsic special variables were updated to support arbitrary terminal sizes, and FreeM was once again able to build and run.
                    117: 
1.36      snw       118: 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 application.
1.1       snw       119: 
                    120: @section Production Readiness
                    121: 
                    122: FreeM is not yet production-ready. There are several show-stopping bugs that preclude a general release for public use:
                    123: 
                    124: @itemize @bullet
                    125: 
                    126: @item
                    127: @code{@ref{VIEW}} commands and @code{@ref{$VIEW()}} functions are used extensively to configure and inspect the run-time behavior of FreeM, rather than the "canonical" SSVN-based approach.
                    128: 
                    129: @item
                    130: Server sockets are not yet implemented.
                    131: 
                    132: @item
                    133: There are some situations that can result in segmentation faults and/or lock-ups.
                    134: 
                    135: @item
                    136: In spite of our best efforts, this manual is not yet complete.
                    137: 
                    138: @end itemize
                    139: 
                    140: @section Contributors
                    141: Current contributors denoted with a @emph{+} following their name and role.
                    142: @cindex contributors, ha-Ashkenaz, Shalom
                    143: @cindex contributors, Best, John
                    144: @cindex contributors, Diamond, Jon
                    145: @cindex contributors, Fox, Ronald L.
                    146: @cindex contributors, Gerum, Winfried
                    147: @cindex contributors, Kreis, Greg
                    148: @cindex contributors, Landis, Larry
                    149: @cindex contributors, Milligan, Lloyd
                    150: @cindex contributors, Morris, Steve
                    151: @cindex contributors, Murray, John
                    152: @cindex contributors, Pastoors, Wilhelm
                    153: @cindex contributors, Schell, Kate
                    154: @cindex contributors, Schofield, Lyle
                    155: @cindex contributors, Stefanik, Jim
                    156: @cindex contributors, Trocha, Axel
                    157: @cindex contributors, Walters, Dick
                    158: @cindex contributors, Whitten, David
                    159: @cindex contributors, Wicksell, David
                    160: @cindex contributors, Willis, Serena
                    161: @cindex contributors, Zeck, Steve
                    162: 
                    163: @itemize @bullet
                    164: 
                    165: @item
                    166: Shalom ha-Ashkenaz (Original Implementer)
                    167: 
                    168: @item
                    169: John Best (IBM i and OS/400)
                    170: 
                    171: @item
                    172: Jon Diamond (Library, Utilities, Conformance)
                    173: 
                    174: @item
                    175: Ronald L. Fox (Initial port to Red Hat 5/libc-6)
                    176: 
                    177: @item
                    178: Winfried Gerum (Code, Advice, MTA coordination)
                    179: 
                    180: @item
                    181: Greg Kreis (Hardhats coordination, Dependencies)
                    182: 
                    183: @item
                    184: Larry Landis (Coordination, Code, Documentation)
                    185: 
                    186: @item
                    187: Rick Marshall (Testing, MDC Conformance) @emph{+}
                    188: 
                    189: @item
                    190: Lloyd Milligan (Code, Testing, Documentation)
                    191: 
                    192: @item
                    193: Steve Morris (Code, Microsoft)
                    194: 
                    195: @item
                    196: John Murray (Code, Conformance)
                    197: 
                    198: @item
                    199: Wilhelm Pastoors (Testing, Documentation)
                    200: 
                    201: @item
                    202: Kate Schell (Coordination, Conformance, MTA, MDC, Advice)
                    203: 
                    204: @item
                    205: Lyle Schofield (Advice, Prioritization, Tracking, Project Management)
                    206: 
                    207: @item
                    208: Jim Stefanik (GNU/Linux on s390x, IBM AIX, IBM z/OS)
                    209: 
                    210: @item
                    211: Axel Trocha (Code, Utilities)
                    212: 
                    213: @item
                    214: Dick Walters (Project Lead, Chief Coordinator, MTA)
                    215: 
                    216: @item
                    217: David Whitten (QA Test Suite, MDC, Advice) @emph{+}
                    218: 
                    219: @item
                    220: David Wicksell (Debugging, Code, Testing) @emph{+}
                    221: 
                    222: @item
                    223: Serena Willis (Current Maintainer and Project Lead) @emph{+}
                    224: 
                    225: @item
                    226: Steve Zeck (Code)
                    227: 
                    228: @end itemize
1.36      snw       229: 
                    230: @node Document Conventions
                    231: @chapter Document Conventions
                    232: @cindex document conventions
                    233: @cindex conventions
                    234: 
                    235: @section Formatting Conventions
                    236: 
                    237: This manual uses the following formatting conventions:
                    238: @itemize
                    239: @item Code examples, filesystem paths, and commands are presented in @code{monospace}
                    240: @item Placeholders where the reader is expected to supply a replacement value are presented in @code{@emph{monospace italics}}, and depending on context, may be surrounded by angle brackets
                    241: @item New terminology is introduced in @emph{proportional italics}
                    242: @end itemize
                    243: 
                    244: @section Definitions
                    245: 
                    246: FreeM uses abbreviations for common language elements:
                    247: 
                    248: @table @asis
                    249: @item @emph{$PREFIX}
                    250: Refers to the base filesystem location within which FreeM is installed. For most distribution methods of FreeM, @emph{$PREFIX} represents either @code{/} or @code{/usr/local}.
1.37    ! snw       251: @item @emph{dlabel}
        !           252: Refers to a label in an M routine, beginning in the first column of the line. Can be a @emph{name} or an @emph{intlit}.
        !           253: @item @emph{entryref}
        !           254: Refers to an M routine entry point, denoted in the format @code{@emph{dlabel} [+@emph{intexpr}][^@emph{routine}]}.
1.36      snw       255: @item @emph{expr}
                    256: Refers to any expression. Often presented in the format @emph{expr V <type>}, where @emph{V} means @emph{giving}; e.g., @emph{expr V lvn} means @emph{expression giving local variable name}.
                    257: @item @emph{glvn}
                    258: Refers to the name of an M global, local, or structured system variable.
                    259: @item @emph{gvn}
                    260: Refers to the name of an M global variable.
                    261: @item @emph{intexpr}
                    262: Refers to an integer expression.
1.37    ! snw       263: @item @emph{intlit}
        !           264: Refers to an integer literal.
1.36      snw       265: @item @emph{ISV}, @emph{isv}
                    266: Refers to an M intrinsic special variable; @code{$JOB} and @code{$IO} are examples of ISVs.
                    267: @item @emph{L}
                    268: Indicates a @emph{list} of the following item, e.g., @emph{L gvn} means @emph{list of global variable names}.
                    269: @item @emph{lvn}
                    270: Refers to the name of an M local variable.
1.37    ! snw       271: @item @emph{strlit}
        !           272: Refers to an M string literal.
1.36      snw       273: @item @emph{ssvn}
                    274: Refers to the name of an M structured system variable.
                    275: @item @emph{tvexpr}
                    276: Refers to a truth-valued expression.
                    277: @end table
                    278: 
1.1       snw       279: @node FreeM Invocation
                    280: @chapter FreeM Invocation
                    281: @cindex invocation, command-line
                    282: @cindex options, command-line
                    283: 
                    284: @section Synopsis
                    285: @example
                    286: $ @command{./freem} [@emph{OPTIONS}...] [[-r <entryref>] | [--routine=<entryref>]]
                    287: @end example
                    288: 
1.28      snw       289: When FreeM loads, it searches the @code{SYSTEM} namespace for the @code{%SYSINIT} routine, and begins executing it.
1.1       snw       290: 
1.28      snw       291: When @code{-r} or @code{--routine} are passed on the command line, FreeM will load and run the specified routine after running @code{%SYSINIT}. Beginning with FreeM 0.1.7, routines invoked in this manner are no longer required to perform their own namespace setup with @code{VIEW} commands.
1.22      snw       292: 
                    293: @section %SYSINIT Routine
                    294: 
1.36      snw       295: The @code{%SYSINIT} routine runs every time a FreeM interpreter process starts. This routine defines some useful constants, enables handling of @code{TRIGGER} events, and handles the execution of code passed via the @code{-x|--execute} or routines passed via @code{-r|--routine}.
1.22      snw       296: 
1.28      snw       297: Do not modify the supplied @code{%SYSINIT} routine to add site-specific startup items. Instead, create a @code{LCLINIT} routine in the @code{USER} namespace of one or more environments. @code{%SYSINIT} will automatically run @code{LCLINIT} each time it starts.
1.1       snw       298: 
                    299: @section Command-Line Options
1.22      snw       300: @cindex options, command-line
1.1       snw       301: 
                    302: @table @asis
                    303: 
                    304: @item @option{-d}, @option{--daemon}
1.22      snw       305: Starts the FreeM environment daemon, exactly one of which must be running at all times in order for FreeM interpreter and fmadm processes to function.
1.1       snw       306: 
                    307: @item @option{-e}, @option{--environment}
                    308: Selects the environment to be used. If no environment is specified, @code{DEFAULT} is used.
                    309: 
                    310: @item @option{-k}, @option{--nofork}
1.22      snw       311: When used with @option{-d} or @option{--daemon}, causes the FreeM environment daemon to run instead in the foreground. Useful for debugging.
1.1       snw       312: 
                    313: @item @option{-S}, @option{--shmsize}
                    314: When used with @option{-d} or @option{--daemon}, specifies the number of bytes of shared memory FreeM will allocate for the @code{LOCK} table, job table, and IPC table. This will determine the maximum number of concurrent FreeM processes and @code{LOCK}s available in this environment. 
                    315: 
                    316: @item @option{-c}, @option{--config}
                    317: Specify a configuration file other than @code{$PREFIX/etc/freem.conf}.
                    318: 
                    319: @item @option{-h}, @option{--help}
                    320: Display a help message showing valid FreeM options.
                    321: 
                    322: @item @option{-i}, @option{--import}
                    323: Causes your UNIX environment variables to be imported into FreeM's local symbol table.
                    324: 
                    325: @item @option{-f}, @option{--filter}
                    326: Allows your M routines to be used as UNIX filters.
                    327: 
                    328: @item @option{-n @emph{<namespace-name>}}, @option{--namespace=@emph{<namespace-name>}}
1.22      snw       329: Selects the FreeM namespace to be entered on startup. Must be defined in @file{/etc/<environment>/freem.conf}.
1.1       snw       330: 
                    331: @item @option{-r @emph{<entryref>}}, @option{--routine=@emph{<entryref>}}
1.28      snw       332: Causes @code{<entryref>} to be executed at load, instead of @code{%SYSINIT}.
1.1       snw       333: 
                    334: @item @option{--standard=@emph{<standard>}}
                    335: Sets the default FreeM dialect to use for new routine buffers.
                    336: 
                    337: Valid values for @code{@emph{<standard>}} are as follows:
                    338: 
                    339: @table @code
                    340: @item @code{M77}
                    341: Restricts FreeM to use only features specified by the 1977 M standard.
                    342: @item @code{M84}
                    343: Restricts FreeM to use only features specified by the 1984 M standard.
                    344: @item @code{M90}
                    345: Restricts FreeM to use only features specified by the 1990 M standard.
                    346: @item @code{M95}
                    347: Restricts FreeM to use only features specified by the 1995 M standard.
                    348: @item @code{MDS}
                    349: Restricts FreeM to use only features proposed by the Millennium Draft Standard.
                    350: @item @code{M5}
                    351: Restricts FreeM to use only features proposed by the upcoming M5 standard.
                    352: @item @code{FREEM}, @code{EXTENDED}
                    353: Removes all standards-based restrictions and allows full access to all FreeM features. This is the default value of @code{$DIALECT}.
                    354: @end table
                    355: 
                    356: Please note that FreeM is not entirely standards-compliant, regardless of the value of @code{@emph{<standard>}}.
                    357: 
                    358: @item @option{-v}, @option{--version}
                    359: Displays FreeM version information.
                    360: 
                    361: @item @option{-x @emph{<mcode>}}, @option{--execute=@emph{<mcode>}}
1.22      snw       362: Executes M code @code{<mcode>} at startup.
1.1       snw       363: 
                    364: @end table
                    365: 
                    366: @section Using FreeM for Shell Scripting
                    367: @cindex routines, as shell scripts
                    368: @cindex shebang line
                    369: @cindex shell scripting
                    370: 
                    371: FreeM M routines can be used as shell scripts by providing a @emph{shebang} line beginning with @code{#!/path/to/freem} as the first line of the routine.
                    372: The following example presumes that FreeM is installed at @file{/usr/local/bin/freem} and uses the @code{USER} namespace:
                    373: 
                    374: @example
                    375: #!/usr/local/bin/freem
                    376: MYSCRIPT ;
                    377:  SET ^$JOB($JOB,"NAMESPACE")="USER"
                    378:  WRITE "This is output from an M routine used as a shell script.",!
                    379:  Q
                    380: @end example
                    381: 
                    382: Currently, the script needs to have a @file{.m} file extension. You will also need to select an appropriate namespace in your script using the @code{SET ^$JOB($JOB,"NAMESPACE")="@emph{<namespace>}"} command before attempting to call other routines or access globals.
                    383: 
                    384: You will also need to set the script's permissions to @emph{executable} in order for this to work:
                    385: 
                    386: @example
                    387: $ chmod +x @emph{myscript.m}
                    388: @end example
                    389: 
1.22      snw       390: @node The FreeM Environment Daemon
                    391: @chapter The FreeM Environment Daemon
1.1       snw       392: @cindex daemon, freem
                    393: 
1.22      snw       394: The FreeM environment daemon manages shared resources for a given FreeM environment. These include the lock table, job table, inter-process communication, and concurrency control for transaction processing. Unlike some M implementations, the FreeM environment daemon does @emph{not} function as a write daemon for global storage.
                    395: 
                    396: One daemon process is required per FreeM environment, and can be started in the following ways, in order of preference:
1.1       snw       397: 
1.22      snw       398: @example
                    399: $ sudo fmadm start environment [-e=<environment-name>]
                    400: @end example
1.1       snw       401: 
                    402: @example
1.22      snw       403: $ freem --daemon [--nofork] [--environment=<environment-name>] [--shmsize=<bytes>]
1.1       snw       404: @end example
                    405: 
                    406: If the daemon is started with @option{--nofork}, it will run in the foreground and its output will be reflected on the terminal. Otherwise, the daemon will run as a child process in the background and immediately return terminal control to the shell. The latter option is recommended in most cases.
                    407: 
                    408: The @option{--environment} option will start the daemon for the specified @emph{environment-name}. The default environment, if unspecified, is called @code{DEFAULT}. If using an environment other than @code{DEFAULT}, interpreter processes that wish to also connect to the same environment must also use the @option{--environment} option when starting, and @code{libfreem} clients must also pass the environment name as the first argument to the @code{freem_init()} function. Environments allow you to run multiple, isolated instances of FreeM on the same machine, whose globals and routines are distinct and unique.
                    409: 
                    410: The @option{--shmsize} option specifies the size in bytes of the FreeM shared memory segment. The default is 4194304 bytes. Increasing the size of the FreeM shared memory segment will, at the cost of increased memory usage, increase the number of concurrent jobs and lock table entries available to the environment; decreasing the size of the segment will have the expected opposite effect. Note that you must also pass @option{--shmsize} with the same number of bytes to any interpreter process to be used with an environment whose daemon uses a non-default shared memory segment size.
                    411: 
                    412: Attempting to start a FreeM interpreter process without a daemon running with the same environment name will result in an error.
                    413: 
                    414: @node The FreeM Direct-Mode Environment
                    415: @chapter The FreeM Direct-Mode Environment
                    416: @cindex command line interface
                    417: @cindex direct mode
                    418: @cindex execution, interactive
                    419: @cindex modes, programmer
                    420: 
                    421: 
                    422: The FreeM direct-mode environment is the mode entered when FreeM is invoked without the use of @option{-r @emph{<entryref>}} or @option{--routine=@emph{<entryref>}}:
                    423: 
                    424: @example
1.32      snw       425: Coherent Logic Development FreeM version 0.64.0-rc1 (x86_64-pc-linux-gnu)
1.1       snw       426: Copyright (C) 2014, 2020, 2021 Coherent Logic Development LLC
                    427: 
                    428: 
                    429: USER>
                    430: @end example
                    431: 
1.25      snw       432: The prompt (@code{DEFAULT.USER>}) displays the current environment and namespace, @code{DEFAULT} and @code{USER}, respsectively. If any uncommitted direct-mode transactions have been started, the prompt will change to reflect the current value of @code{@ref{$TLEVEL}}:
1.1       snw       433: 
                    434: @example
1.22      snw       435: TL1:DEFAULT.USER>
1.1       snw       436: @end example
                    437: 
                    438: In the above example, @code{TL1} indicates that @code{@ref{$TLEVEL}} is currently @emph{1}.
                    439: 
                    440: @section Direct-Mode Commands
                    441: 
                    442: When you are in direct mode, in addition to M commands, a number of internal commands are available to help developers be more productive:
                    443: 
                    444: @table @asis
                    445: 
                    446: @item @command{?}
                    447: Accesses FreeM online help. Requires GNU @command{info(1)} to be installed on your local system.
                    448: 
                    449: @item @command{events}
                    450: Writes a list of @emph{event classes} and their @code{ABLOCK} counts:
                    451: 
                    452: @example
1.22      snw       453: DEFAULT.USER> events
1.1       snw       454:  
                    455: Event Class          Processing Mode ABLOCK Count
                    456: -----------          --------------- ------------
                    457: COMM                 Disabled        0
                    458: HALT                 Disabled        0
                    459: IPC                  Disabled        0
                    460: INTERRUPT            Disabled        0
                    461: POWER                Disabled        0
                    462: TIMER                Disabled        0
                    463: USER                 Disabled        0
                    464: WAPI                 Disabled        0
                    465: TRIGGER              Disabled        0
                    466: @end example
                    467: 
                    468: 
                    469: @anchor{trantab}
                    470: @item @command{trantab}
                    471: Displays information about any uncommitted transactions currently in-flight for this process.
                    472: 
1.22      snw       473: @anchor{glstat}
                    474: @item @command{trantab}
                    475: Displays statistics about globals that have been opened in the current FreeM process.
                    476: 
1.1       snw       477: @anchor{jobtab}
                    478: @item @command{jobtab}
                    479: Displays a summary of the FreeM job table.
                    480: 
                    481: @anchor{locktab}
                    482: @item @command{locktab}
                    483: Displays a list of @code{LOCK}s held in the current environment.
                    484: 
                    485: @anchor{rbuf}
                    486: @item @command{rbuf}
                    487: Lists the status of all FreeM routine buffers.
                    488: 
                    489: @anchor{wh}
                    490: @item @command{wh}
                    491: Forces an immediate flush of this process's @code{readline} history buffer to disk.
                    492: 
                    493: @anchor{shmstat}
                    494: @item @command{shmstat}
                    495: Displays the configuration of FreeM shared memory. Intended only for advanced debugging of the FreeM environment.
                    496: 
                    497: @anchor{shmpages}
                    498: @item @command{shmpages}
                    499: Lists the status of each FreeM shared memory page. Intended only for advanced debugging of the FreeM environment.
                    500: 
                    501: @anchor{history}
                    502: @item @command{history}
                    503: Prints a list of all the direct-mode commands you have entered across all sessions.
                    504: 
                    505: @anchor{rcl}
                    506: @item @command{rcl @emph{<history-index>}}
                    507: Allows you to recall command number @emph{<history-index>} and run it again. Obtain the value for @emph{<history-index>} from the output of the @command{history} command.
                    508: 
                    509: @item @command{!!}
                    510: Launches a subshell within the FreeM direct mode, allowing the user to run operating system commands.
                    511: 
                    512: @example
1.22      snw       513: DEFAULT.USER> !!
1.1       snw       514: 
                    515: Type Ctrl-D to exit from the shell
                    516: $ uname -a
                    517: Linux hesperos 4.19.0-17-amd64 #1 SMP Debian 4.19.194-3 (2021-07-18) x86_64 GNU/Linux
                    518: $ exit
                    519: 
1.22      snw       520: DEFAULT.USER> 
1.1       snw       521: @end example
                    522: 
                    523: @item @command{!@emph{<external-command>}}
1.28      snw       524: Invokes a shell to run @emph{<external-command>} from within FreeM. This temporarily disables @command{SIGALRM} handling in FreeM, which may interrupt the use of event-driven M programming commands including @command{ASTART} and @command{ASTOP}.
1.1       snw       525: 
                    526: If the @command{>} character is supplied immediately preceding @emph{<external-command>}, FreeM will append the contents of an M local or global variable referenced in @code{^$JOB($JOB,"PIPE_GLVN")} to the standard input stream of @emph{<external-command>}.
                    527: 
                    528: If the @command{<} character is supplied immediately preceding @emph{<external-command>}, FreeM will take the standard output stream of @emph{<external-command>} and store it in M local or global variable referenced by @code{^$JOB($JOB,"PIPE_GLVN")}.
                    529: 
                    530: The data value in the unsubscripted M local or global contains the number of lines in the input or output. Subscripts @code{(1)..(@emph{n})} contain the data for lines 1-@emph{n}.
                    531: 
                    532: @end table
                    533: 
                    534: @cindex HALT, in direct-mode
                    535: If you issue a @code{@ref{HALT}} command at the direct-mode prompt, you will exit out of FreeM. However, if you issue a @code{@ref{HALT}} command when @code{@ref{$TLEVEL}} is greater than zero, you will be given the opportunity to commit or rollback any pending transactions:
                    536: 
                    537: @example
1.22      snw       538: DEFAULT.USER> TSTART
1.1       snw       539:  
                    540: 
1.22      snw       541: TL1:DEFAULT.USER> SET ^MYGLOBAL=1
1.1       snw       542:  
                    543:  
1.22      snw       544: TL1:DEFAULT.USER> HALT
1.1       snw       545:  
                    546: UNCOMMITTED TRANSACTIONS EXIST:
                    547:  
                    548:  $TLEVEL 1*
                    549:   Operations for Transaction ID: k8xj1de
                    550:   1:   action = 0  key = ^MYGLOBAL  data = 1
                    551:  
                    552: Would you like to c)ommit or r)ollback the above transactions and their operations? ($TLEVEL = 1) r
                    553: 
                    554: 
                    555: Transactions have been rolled back.
                    556: @end example
                    557: 
                    558: In the above example, the user selected @code{r} to rollback the single pending transaction.
                    559: 
                    560: @section REPL Functionality
                    561: @cindex REPL, direct-mode
                    562: 
                    563: FreeM direct mode allows you to enter M expressions directly from the direct-mode prompt, as long as they begin with a number:
                    564: 
                    565: @example
1.22      snw       566: DEFAULT.USER> S DENOM=10
1.1       snw       567:  
                    568:  
1.22      snw       569: DEFAULT.USER> 100/DENOM
1.1       snw       570:  
                    571: 10
1.22      snw       572: DEFAULT.USER> 
1.1       snw       573: @end example
                    574: 
                    575: Such expressions will be immediately evaluated, and the result printed on @code{@ref{$IO}}.
                    576: 
1.36      snw       577: @node Debugging
                    578: @chapter Debugging
                    579: @cindex debugging
                    580: 
                    581: @section Debugging Synopsis
                    582: FreeM includes an interactive debugger, entered using the @code{BREAK "DEBUG"} command. The debugger is also entered if @code{Ctrl-C} is pressed, @code{Ctrl-C} handling is enabled, and you are in direct mode.
                    583: 
                    584: If you would like to enter the debugger automatically each time an error is encountered, add the following to your @code{LCLINIT} routine:
                    585: 
                    586: @example
                    587: S $ETR="B ""DEBUG"""
                    588: @end example
                    589: 
                    590: @section Debugging Commands
                    591: The debugger uses its own unique command language, where M commands are unavailable. Commands are as follows:
                    592: 
                    593: @table @asis
                    594: @item @code{exit}, @code{quit}
                    595: Exits the debugger and returns to direct mode or normal program execution.
                    596: @item @code{e} @emph{glvn}, @code{examine} @emph{glvn}
                    597: Prints the value of @emph{glvn} to the terminal.
                    598: @item @code{t}, @code{trace}
                    599: Toggles @emph{trace mode} on and off. When trace mode is on, FreeM will display information about each @code{DO} or @code{GOTO} command encountered, including the routine which invoked the branch, which type of branch was invoked, and the target of the branch.
                    600: @item @code{s}, @code{step}
                    601: Single-steps through FreeM code command-by-command.
                    602: @item @code{n}, @code{next}
                    603: Single-steps through FreeM code line-by-line.
                    604: @item @code{c}, @code{cont}, @code{continue}
                    605: Resumes normal program execution, disabling single-step mode.
                    606: @item @code{bt}, @code{backtrace}
                    607: Produces a stack trace.
                    608: @item @code{h}, @code{halt}
                    609: Halts the process being debugged and returns control to the operating system.
                    610: @item @code{w [[+|-|?]@emph{<glvn>}]}, @code{watch [[+|-|?]@emph{<glvn>}]}
                    611: With no arguments, toggles watchpoints on and off. With @code{+}, adds @emph{<glvn>} to the watchlist. With @code{-}, removes @emph{<glvn>} from the watchlist. With @code{?}, queries the watch status of @emph{<glvn>}.
                    612: @end table
                    613: 
1.1       snw       614: @node Directives
                    615: @chapter Directives
                    616: @cindex directives
                    617: 
                    618: In FreeM, a directive is an instruction embedded in an M comment, and passed to the interpreter to affect a change that is specific to the current routine only.
                    619: 
                    620: The format of a directive is @code{;%@emph{<directive-name>}}, where @code{@emph{<directive-name>}} is one of the directives listed below.
                    621: 
                    622: @menu
                    623: * %DIALECT::            Sets the M dialect in effect.
                    624: @end menu
                    625: 
                    626: @anchor{%DIALECT}
                    627: @section %DIALECT
                    628: @cindex %DIALECT
                    629: @cindex directives, %DIALECT
                    630: 
                    631: Sets the M dialect in effect for the current routine buffer; also sets the @code{$DIALECT} special variable to match. See also @ref{$DIALECT}.
                    632: 
                    633: @emph{Syntax}
                    634: 
                    635: @example
                    636: ;%DIALECT @emph{<dialect>}
                    637: @end example
                    638: 
                    639: Valid values for @code{@emph{<dialect>}} are as follows:
                    640: 
                    641: @table @code
                    642: @item @code{M77}
                    643: Restricts FreeM to use only features specified by the 1977 M standard.
                    644: @item @code{M84}
                    645: Restricts FreeM to use only features specified by the 1984 M standard.
                    646: @item @code{M90}
                    647: Restricts FreeM to use only features specified by the 1990 M standard.
                    648: @item @code{M95}
                    649: Restricts FreeM to use only features specified by the 1995 M standard.
                    650: @item @code{MDS}
                    651: Restricts FreeM to use only features proposed by the Millennium Draft Standard.
                    652: @item @code{M5}
                    653: Restricts FreeM to use only features proposed by the upcoming M5 standard.
                    654: @item @code{FREEM}, @code{EXTENDED}
                    655: Removes all standards-based restrictions and allows full access to all FreeM features. This is the default value of @code{%DIALECT}.
                    656: @end table
                    657: 
                    658: Please note that FreeM is not entirely standards-compliant, regardless of the value of @code{%DIALECT}.
                    659: 
                    660: 
                    661: @node Intrinsic Special Variables
                    662: @chapter Intrinsic Special Variables
                    663: @cindex variables, intrinsic special
                    664: 
                    665: @menu
                    666: * $DEVICE::                  $IO device status.
                    667: * $DIALECT::                 Current M dialect.
                    668: * $ECODE::                   Latest M error code.
                    669: * $ESTACK::                  Error stack info.
                    670: * $ETRAP::                   Standard error handler code.
                    671: * $HOROLOG::                 Current date and time.
                    672: * $IO::                      Current I/O device.
                    673: * $JOB::                     PID of current process.
                    674: * $KEY::                     Characters terminating last @code{READ} command.
                    675: * $PDISPLAY::                Current primary MWAPI display.
                    676: * $PRINCIPAL::               I/O channel of terminal.
                    677: * $REFERENCE::               Most recent global reference.
                    678: * $QUIT::                    Whether a @code{QUIT} command requires an argument in the current execution context.
                    679: * $STACK::                   Current program execution stack level.
                    680: * $STORAGE::                 Number of bytes available in the heap.
                    681: * $SYSTEM::                  MDC system ID of FreeM.
                    682: * $TEST::                    Truth value of last conditional expression or result of certain @code{LOCK} operations.
                    683: * $TLEVEL::                  Current level of transaction nesting.
                    684: * $WITH::                    Current variable prefix set by @code{WITH} command.
                    685: * $X::                       Current horizontal screen position.
                    686: * $Y::                       Current vertical screen position.
                    687: * $ZA::                      Current position of file on @code{$IO}.
                    688: * $ZB::                      Most recent keystroke.
                    689: * $ZCONTROLC::               Control-C handling flag.
                    690: * $ZDATE::                   Current date in locale-specific representation.
                    691: * $ZERROR::                  Last error message.
                    692: * $ZHOROLOG::                Date and time, including milliseconds.
                    693: * $ZINRPT::                  State of the interrupt enable/disable flag.
                    694: * $ZJOB::                    PID of parent process, if applicable.
                    695: * $ZLOCAL::                  Last local variable reference.
                    696: * $ZNAME::                   Name of current M routine.
                    697: * $ZPRECISION::              Digits of arithmetical precision.
                    698: * $ZREFERENCE::              Last gvn referenced.
                    699: * $ZSYSTEM::                 Return value of last external command.
                    700: * $ZTIME::                   Current time in locale-specific representation.
                    701: * $ZTRAP::                   Entryref to be executed on error condition.
                    702: * $ZUT::                     Microseconds since the UNIX epoch.
                    703: * $ZVERSION::                Version of FreeM and GNU host triplet.
                    704: @end menu 
                    705: 
                    706: @node $DEVICE
                    707: @section $DEVICE
                    708: @cindex $DEVICE
                    709: @cindex intrinsic special variables, $DEVICE
                    710: 
                    711: Returns the status of the device currently in use.
                    712: 
                    713: If @code{$DEVICE} returns @emph{1}, an error condition exists on the current device. In this case, there will be two additional fields separated by commas, indicating the internal FreeM error code representing the error present on the device and a text explanation of the error.
                    714: 
                    715: @node $DIALECT
                    716: @section $DIALECT
                    717: @cindex $DIALECT
                    718: @cindex intrinsic special variables, $DIALECT
                    719: 
                    720: Returns or sets the language dialect of the current routine.
                    721: 
                    722: Valid values for @code{$DIALECT} are as follows:
                    723: 
                    724: @table @code
                    725: @item @code{M77}
                    726: Restricts FreeM to use only features specified by the 1977 M standard.
                    727: @item @code{M84}
                    728: Restricts FreeM to use only features specified by the 1984 M standard.
                    729: @item @code{M90}
                    730: Restricts FreeM to use only features specified by the 1990 M standard.
                    731: @item @code{M95}
                    732: Restricts FreeM to use only features specified by the 1995 M standard.
                    733: @item @code{MDS}
                    734: Restricts FreeM to use only features proposed by the Millennium Draft Standard.
                    735: @item @code{M5}
                    736: Restricts FreeM to use only features proposed by the upcoming M5 standard.
                    737: @item @code{FREEM}, @code{EXTENDED}
                    738: Removes all standards-based restrictions and allows full access to all FreeM features. This is the default value of @code{$DIALECT}.
                    739: @end table
                    740: 
                    741: Please note that FreeM is not entirely standards-compliant, regardless of the value of @code{$DIALECT}.
                    742: 
                    743: @node $ECODE
                    744: @section $ECODE
                    745: @cindex $ECODE
                    746: @cindex intrinsic special variables, $ECODE
                    747: 
                    748: Returns a comma-delimited list of error conditions currently present, and is writable. An empty @code{$ECODE} indicates no errors.
                    749: 
1.28      snw       750: Writing a value in the format @code{,<error-code>,} into @code{$ECODE} will raise that error condition.
                    751: 
1.1       snw       752: @node $ESTACK
                    753: @section $ESTACK
                    754: @cindex $ESTACK
                    755: @cindex intrinsic special variables, $ESTACK
                    756: 
                    757: Returns the depth of the program execution stack since the last time @code{$ESTACK} was @code{NEW}ed. @code{NEW}-able, but not @code{SET}-able. Differs from the @code{@ref{$STACK}} ISV in that it is @code{@ref{NEW}}-able, and resets to a value of 0 when @code{@ref{NEW}}ed.
                    758: 
                    759: @node $ETRAP
                    760: @section $ETRAP
                    761: @cindex $ETRAP
                    762: @cindex intrinsic special variables, $ETRAP
                    763: 
                    764: Sets or retrieves the M code that is run when an error is encountered or @code{@ref{$ECODE}} is set to a non-blank value. @code{$ETRAP} code executes when @code{$ECODE} becomes non-blank.
                    765: 
                    766: 
                    767: @node $HOROLOG
                    768: @section $HOROLOG
                    769: @cindex $HOROLOG
                    770: @cindex intrinsic special variables, $HOROLOG
                    771: 
                    772: Returns a string containing the current date and time as @code{<days>,<seconds>}, where @code{<days>} represents the number of days since the M epoch (midnight on 31 December 1840),
                    773: and @code{<seconds>} represents the number of seconds since the most recent midnight.
                    774: 
                    775: @cartouche
                    776: @quotation
                    777: @emph{FreeM Extension}
                    778: 
                    779: In FreeM, @code{$HOROLOG} is @code{@ref{SET}}table. Setting @code{$HOROLOG} will set the system clock if your user account has the appropriate permissions. If your user account does not have permissions to modify the system clock, FreeM will raise a @code{ZPROTECT} error.
                    780: @end quotation
                    781: @end cartouche
                    782: 
                    783: @node $IO
                    784: @section $IO
                    785: @cindex $IO
                    786: @cindex intrinsic special variables, $IO
                    787: 
                    788: Represents the current input/output device. Read-only.
                    789: 
                    790: @node $JOB
                    791: @section $JOB
                    792: @cindex $JOB
                    793: @cindex intrinsic special variables, $JOB
                    794: 
                    795: Represents the process ID of the FreeM instance currently in use.
                    796: 
                    797: @node $KEY
                    798: @section $KEY
                    799: @cindex $KEY
                    800: @cindex intrinsic special variables, $KEY
                    801: 
                    802: Represents the sequence of control characters that terminated the last @code{@ref{READ}} command on @code{@ref{$IO}}.
                    803: 
                    804: @node $PDISPLAY
                    805: @section $PDISPLAY
                    806: @cindex $PDISPLAY
                    807: @cindex intrinsic special variables, $PDISPLAY
                    808: 
                    809: Represents the current principal display for M Windowing API operations. Commonly used as an index into the @code{@ref{^$DISPLAY}} structured system variable.
                    810: 
                    811: @node $PRINCIPAL
                    812: @section $PRINCIPAL
                    813: @cindex $PRINCIPAL
                    814: @cindex intrinsic special variables, $PRINCIPAL
                    815: 
                    816: Represents the primary input/output device. Usually a terminal or virtual terminal.
                    817: 
                    818: @node $REFERENCE
                    819: @section $REFERENCE
                    820: @cindex $REFERENCE
                    821: @cindex intrinsic special variables, $REFERENCE
                    822: 
                    823: Returns the last @emph{glvn} referenced. Can be @code{@ref{SET}}, and also stacked with @code{@ref{NEW}}.
                    824: 
                    825: @node $QUIT
                    826: @section $QUIT
                    827: @cindex $QUIT
                    828: @cindex intrinsic special variables, $QUIT
                    829: 
                    830: If the current execution context was invoked as an extrinsic function, @code{$QUIT} returns @emph{1}. Otherwise, returns @emph{0}.
                    831: 
                    832: When @code{$QUIT} returns @emph{1}, a subsequent @code{@ref{QUIT}} command must have an argument.
                    833: 
                    834: @node $STACK
                    835: @section $STACK
                    836: @cindex $STACK
                    837: @cindex intrinsic special variables, $STACK
                    838: 
                    839: Represents the current stack level.
                    840: 
                    841: @node $STORAGE
                    842: @section $STORAGE
                    843: @cindex $STORAGE
                    844: @cindex intrinsic special variables, $STORAGE
                    845: 
                    846: Represents the number of bytes of free space available in FreeM's heap.
                    847: 
                    848: @node $SYSTEM
                    849: @section $SYSTEM
                    850: @cindex $SYSTEM
                    851: @cindex intrinsic special variables, $SYSTEM
                    852: 
                    853: Returns the MDC system ID of FreeM, as well as the environment ID of the current environment.
                    854: 
                    855: @node $TEST
                    856: @section $TEST
                    857: @cindex $TEST
                    858: @cindex intrinsic special variables, $TEST
                    859: 
                    860: @code{$TEST} is a writable, @code{@ref{NEW}}-able ISV that is @emph{1} if the most recently evaluated expression was @emph{true}. Otherwise, returns @emph{0}.
                    861: 
                    862: @code{$TEST} is implicitly @code{NEW}ed when entering a new stack frame for extrinsic functions and argumentless @code{@ref{DO}}. @code{$TEST}
                    863: is @emph{not} implicitly @code{NEW}ed when a new stack frame is entered with an argumented @code{DO}.
                    864: 
                    865: For single-line @code{@ref{IF}} or @code{@ref{ELSE}} expressions, you may use @code{@ref{THEN}} to stack @code{$TEST} until the end of the line. All new code should employ @code{THEN} in this manner, as stacking @code{$TEST} prevents a wide range of coding errors that can be very challenging to detect and eliminate.
                    866: 
                    867: @node $TLEVEL
                    868: @section $TLEVEL
                    869: @cindex $TLEVEL
                    870: @cindex intrinsic special variables, $TLEVEL
                    871: 
                    872: Returns a numeric value indicating the current level of transaction nesting in the process. When @code{$TLEVEL} is greater than @emph{0},
                    873: uncommitted transactions exist.
                    874: 
                    875: @node $WITH
                    876: @section $WITH
                    877: @cindex $WITH
                    878: @cindex intrinsic special variables, $WITH
                    879: 
                    880: Returns the variable prefix set by the @code{@ref{WITH}} command.
                    881: 
                    882: @node $X
                    883: @section $X
                    884: @cindex $X
                    885: @cindex intrinsic special variables, $X
                    886: 
                    887: Represents the current column position of the FreeM cursor.
                    888: 
                    889: @cartouche
                    890: @quotation
                    891: In FreeM, setting @code{$X} will move the FreeM cursor.
                    892: @end quotation
                    893: @end cartouche
                    894: 
                    895: 
                    896: @node $Y
                    897: @section $Y
                    898: @cindex $Y
                    899: @cindex intrinsic special variables, $Y
                    900: 
                    901: Represents the current row position of the FreeM cursor.
                    902: 
                    903: @cartouche
                    904: @quotation
                    905: In FreeM, setting @code{$Y} will move the FreeM cursor.
                    906: @end quotation
                    907: @end cartouche
                    908: 
                    909: 
                    910: @node $ZA
                    911: @section $ZA
                    912: @cindex $ZA
                    913: @cindex intrinsic special variables, $ZA
                    914: @cindex intrinsic special variables, implementation-specific
                    915: 
                    916: On the @code{HOME} device, always @code{0}. On other devices, returns the current position of the file opened on I/O channel @code{@ref{$IO}}.
                    917: 
                    918: @node $ZB
                    919: @section $ZB
                    920: @cindex $ZB
                    921: @cindex intrinsic special variables, $ZB
                    922: @cindex intrinsic special variables, implementation-specific
                    923: 
                    924: Represents the last keystroke.
                    925: 
                    926: @node $ZCONTROLC
                    927: @section $ZCONTROLC
                    928: @cindex $ZCONTROLC
                    929: @cindex intrinsic special variables, $ZCONTROLC
                    930: @cindex intrinsic special variables, implementation-specific
                    931: 
                    932: Returns the status of the Ctrl-C flag and resets it to @emph{false}.
                    933: 
                    934: @node $ZDATE
                    935: @section $ZDATE
                    936: @cindex $ZDATE
                    937: @cindex intrinsic special variables, $ZDATE
                    938: @cindex intrinsic special variables, implementation-specific
                    939: 
                    940: Returns the current date, in the preferred representation for the current system locale.
                    941: 
                    942: @node $ZERROR
                    943: @section $ZERROR
                    944: @cindex $ZERROR
                    945: @cindex intrinsic special variables, $ZERROR
                    946: @cindex intrinsic special variables, implementation-specific
                    947: 
                    948: Returns the last error message.
                    949: 
                    950: @node $ZHOROLOG
                    951: @section $ZHOROLOG
                    952: @cindex $ZHOROLOG
                    953: @cindex intrinsic special variables, $ZHOROLOG
                    954: @cindex intrinsic special variables, implementation-specific
                    955: 
                    956: Output @code{@ref{$HOROLOG}}-style time, with the addition of milliseconds.
                    957: 
                    958: @node $ZINRPT
                    959: @section $ZINRPT
                    960: @cindex $ZINRPT
                    961: @cindex intrinsic special variables, $ZINRPT
                    962: @cindex intrinsic special variables, implementation-specific
                    963: 
                    964: Gets or sets the interrupt enable/disable flag.
                    965: 
                    966: @node $ZJOB
                    967: @section $ZJOB
                    968: @cindex $ZJOB
                    969: @cindex intrinsic special variables, $ZJOB
                    970: @cindex intrinsic special variables, implementation-specific
                    971: 
                    972: Returns the @code{@ref{$JOB}} value of the parent process if the current process was started by a @code{@ref{JOB}} command. Otherwise, returns an empty string.
                    973: 
                    974: @node $ZLOCAL
                    975: @section $ZLOCAL
                    976: @cindex $ZLOCAL
                    977: @cindex intrinsic special variables, $ZLOCAL
                    978: @cindex intrinsic special variables, implementation-specific
                    979: 
                    980: Returns the last local variable referenced.
                    981: 
                    982: @node $ZNAME
                    983: @section $ZNAME
                    984: @cindex $ZNAME
                    985: @cindex intrinsic special variables, $ZNAME
                    986: @cindex intrinsic special variables, implementation-specific
                    987: 
                    988: Returns the name of the current routine.
                    989: 
                    990: @node $ZPRECISION
                    991: @section $ZPRECISION
                    992: @cindex $ZPRECISION
                    993: @cindex intrinsic special variables, $ZPRECISION
                    994: @cindex intrinsic special variables, implementation-specific
                    995: 
                    996: Gets or sets the number of digits of numeric precision used for fixed-point decimal arithmetic. If @code{^$JOB($JOB,"MATH")} is @code{IEEE754}, @code{$ZPRECISION} defaults to 16 digits, with a maximum of 16 digits. If @code{^$JOB($JOB,"MATH")} is @code{FIXED}, @code{$ZPRECISION} defaults to 100 digits, with a maximum of 20,000 digits.
                    997: 
                    998: @xref{^$JOB}.
                    999: 
                   1000: @node $ZREFERENCE
                   1001: @section $ZREFERENCE
                   1002: @cindex $ZREFERENCE
                   1003: @cindex intrinsic special variables, $ZREFERENCE
                   1004: @cindex intrinsic special variables, implementation-specific
                   1005: 
                   1006: Returns the last @emph{gvn} referenced.
                   1007: 
                   1008: @node $ZSYSTEM
                   1009: @section $ZSYSTEM
                   1010: @cindex $ZSYSTEM
                   1011: @cindex intrinsic special variables, $ZSYSTEM
                   1012: @cindex intrinsic special variables, implementation-specific
                   1013: 
                   1014: Represents the return value of the last external command run with @code{!}.
                   1015: 
                   1016: @node $ZTIME
                   1017: @section $ZTIME
                   1018: @cindex $ZTIME
                   1019: @cindex intrinsic special variables, $ZTIME
                   1020: @cindex intrinsic special variables, implementation-specific
                   1021: 
                   1022: Returns the system time in the preferred representation for the current system locale.
                   1023: 
                   1024: @node $ZTRAP
                   1025: @section $ZTRAP
                   1026: @cindex $ZTRAP
                   1027: @cindex intrinsic special variables, $ZTRAP
                   1028: @cindex intrinsic special variables, implementation-specific
                   1029: 
                   1030: Sets or retrieves the entryref to be executed when an M program execution error occurs under FreeM-style or DSM 2.0-style error processing.
                   1031: 
                   1032: In FreeM-style error processing, @code{$ZTRAP} is specific to each program execution stack level.
                   1033: 
                   1034: In DSM 2.0-style error processing, @code{$ZTRAP} is the same for all program execution stack levels.
                   1035: 
                   1036: When FreeM encounters an error, if @code{$ZTRAP} is nonempty and @code{$ETRAP} is empty, FreeM will perform an implicit @code{@ref{GOTO}} to the entryref indicated in @code{$ZTRAP}.
                   1037: 
                   1038: If @code{$ETRAP} is nonempty when FreeM encounters an error, the value of @code{$ZTRAP} is ignored, whether FreeM-style or DSM 2.0-style error processing is enabled.
                   1039: 
                   1040: @node $ZUT
                   1041: @section $ZUT
                   1042: @cindex $ZUT
                   1043: @cindex intrinsic special variables, $ZUT
                   1044: @cindex intrinsic special variables, implementation-specific
                   1045: 
                   1046: Returns the number of microseconds elapsed since the UNIX epoch (Jan 1, 1970 0:00:00).
                   1047: 
                   1048: @node $ZVERSION
                   1049: @section $ZVERSION
                   1050: @cindex $ZVERSION
                   1051: @cindex intrinsic special variables, $ZVERSION
                   1052: @cindex intrinsic special variables, implementation-specific
                   1053: 
                   1054: Returns the version of FreeM in use, as well as the GNU host triplet for the current FreeM build.
                   1055: 
                   1056: See @emph{https://wiki.osdev.org/Target_Triplet}.
                   1057: 
                   1058: @node Intrinsic Functions
                   1059: @chapter Intrinsic Functions
                   1060: 
                   1061: @menu
                   1062: * $ASCII()::                            Return ASCII code for character in string.
                   1063: * $CHAR()::                             Return character for one or more ASCII codes.
                   1064: * $DATA()::                             Retrieve definition and characteristics of array node.
                   1065: * $EXTRACT()::                          Return a substring of a string.
                   1066: * $FIND()::                             Find position of substring within string.
                   1067: * $FNUMBER()::                          Format a number according to formatting codes.
                   1068: * $GET()::                              Return value of glvn or a default if undefined.
                   1069: * $INSTANCEOF()::                       Determine if lvn is an instance of a class.
                   1070: * $JUSTIFY()::                          Right-justify a string based on specified length.
                   1071: * $LENGTH()::                           Return length or delimiter-based piece count of string.
                   1072: * $NAME()::                             Return canonical name from string representation of glvn.
                   1073: * $NEXT()::                             Return next numeric subscript following given glvn.
                   1074: * $ORDER()::                            Return next subscript at same level of specified glvn.
                   1075: * $PIECE()::                            Return one or more delimited pieces of a string.
                   1076: * $QLENGTH()::                          Return subscript count of glvn.
                   1077: * $QSUBSCRIPT()::                       Return a specified subscript from glvn.
                   1078: * $QUERY()::                            Return next subscript of specified glvn.
                   1079: * $RANDOM()::                           Return pseudorandom integer up to a maximum value.
                   1080: * $REVERSE()::                          Reverse a string.
                   1081: * $SELECT()::                           Return value from first true condition in list of expressions.
                   1082: * $STACK()::                            Return information about the program stack.
                   1083: * $TEXT()::                             Return line of code from a routine.
                   1084: * $TRANSLATE()::                        Substitute specified characters in a string.
                   1085: * $TYPE()::                             Return class of the specified lvn.
                   1086: * $VIEW()::                             Retrieve implementation-specific information.
                   1087: * $ZBOOLEAN()::                         Perform boolean operations on numeric arguments.
                   1088: * $ZCALL()::                            Unknown.
                   1089: * $ZCRC()::                             Generate checksum of a string argument.
                   1090: * $ZDATA()::                            Unknown.
                   1091: * $ZDATE()::                            Convert @code{@ref{$HOROLOG}} string into human-readable date.
                   1092: * $ZEDIT()::                            Unknown.
                   1093: * $ZHOROLOG()::                         Convert date/time values to @code{@ref{$HOROLOG}} format.
                   1094: * $ZKEY()::                             Unknown.
                   1095: * $ZLENGTH()::                          Unknown.
                   1096: * $ZLSD()::                             Compute Levenshtein distance between two arguments.
                   1097: * $ZM()::                               Unknown.
                   1098: * $ZNAME()::                            Unknown.
                   1099: * $ZNEXT()::                            Unknown.
                   1100: * $ZORDER()::                           Unknown.
                   1101: * $ZPIECE()::                           Unknown.
                   1102: * $ZPREVIOUS()::                        Unknown.
                   1103: * $ZREPLACE()::                         Replace all instances of a substring within a string.
                   1104: * $ZSYNTAX()::                          Perform syntax check on string argument.
                   1105: * $ZTIME()::                            Convert a @code{@ref{$HOROLOG}} string into human-readable time.
                   1106: @end menu
                   1107: 
                   1108: @node $ASCII()
                   1109: @section $ASCII
                   1110: @cindex $ASCII
                   1111: @cindex intrinsic functions, $ASCII
                   1112: 
                   1113: Returns the ASCII code (in decimal) for one character in a string.
                   1114: 
                   1115: @example
                   1116: SET RESULT=$ASCII(@emph{<string>}[,@emph{<index>}])
                   1117: @end example
                   1118: 
                   1119: 
                   1120: If @emph{<index>} is not supplied, @code{$ASCII} will return the ASCII code of the first character. Otherwise, returns the ASCII code of the character at position @emph{<index>}.
                   1121: 
                   1122: @node $CHAR()
                   1123: @section $CHAR
                   1124: @cindex $CHAR
                   1125: @cindex intrinsic functions, $CHAR
                   1126: 
                   1127: Returns a string of characters corresponding to a list of ASCII codes.
                   1128: 
                   1129: @example
                   1130: SET RESULT=$CHAR(@emph{<ascii-code>}[,@emph{<ascii-code>},...])
                   1131: @end example
                   1132: 
                   1133: @node $DATA()
                   1134: @section $DATA
                   1135: @cindex $DATA
                   1136: @cindex intrinsic functions, $DATA
                   1137: 
                   1138: Returns a numeric value 0, 1, 10, or 11, depending on whether a referenced node is defined, has data, or has children:
                   1139: 
                   1140: @example
                   1141: SET RESULT=$DATA(@emph{<node>})
                   1142: @end example
                   1143: 
                   1144: The return values are as follows:
                   1145: 
                   1146: @example
                   1147: 0: @emph{<node>} is undefined
                   1148: 1: @emph{<node>} has data but no children
                   1149: 10: @emph{<node>} has children but no data
                   1150: 11: @emph{<node>} has children and data
                   1151: @end example
                   1152: 
                   1153: @node $EXTRACT()
                   1154: @section $EXTRACT
                   1155: @cindex $EXTRACT
                   1156: @cindex intrinsic functions, $EXTRACT
                   1157: 
                   1158: Extracts a substring of a string.
                   1159: 
                   1160: The first argument is the source string.
                   1161: 
                   1162: The optional second argument specifies the starting position of the substring to extract, and defaults to @code{1}.
                   1163: 
                   1164: The optional third argument specifies the ending position of the substring to extract, and defaults to the value of the second argument, or @code{1}.
                   1165: 
                   1166: This example will extract the string @emph{FreeM} into the local variable @code{M}.
                   1167: 
                   1168: @example
                   1169: SET NAME="FreeM is the best!"
                   1170: SET M=$EXTRACT(NAME,1,5)
                   1171: @end example
                   1172: 
                   1173: It is also possible to use @code{$EXTRACT} on the left-hand side of a @code{SET} assignment in order to modify a substring:
                   1174: 
                   1175: @example
1.22      snw      1176: DEFAULT.USER> SET FOO="ABCDEFG"
1.1       snw      1177: 
                   1178: 
1.22      snw      1179: DEFAULT.USER> SET $EXTRACT(FOO,1,3)="XYZ"
1.1       snw      1180: 
                   1181: 
1.22      snw      1182: DEFAULT.USER> WRITE FOO
1.1       snw      1183: 
                   1184: XYZDEFG
                   1185: @end example
                   1186: 
                   1187: @node $FIND()
                   1188: @section $FIND
                   1189: @cindex $FIND
                   1190: @cindex intrinsic functions, $FIND
                   1191: 
                   1192: Finds the character immediately following the first occurence of a substring within a string.
                   1193: 
                   1194: The first argument is the source string.
                   1195: 
                   1196: The second argument is the substring to be located.
                   1197: 
                   1198: The optional third argument indicates the position within the source string at which to begin searching.
                   1199: 
                   1200: @node $FNUMBER()
                   1201: @section $FNUMBER
                   1202: @cindex $FNUMBER
                   1203: @cindex intrinsic functions, $FNUMBER
                   1204: 
                   1205: Formats a number according to a particular set of formatting codes.
                   1206: 
                   1207: The first argument is the number to format.
                   1208: 
1.22      snw      1209: The second argument is the series of formatting codes:
                   1210: 
                   1211: @table @asis
                   1212: @item 'P' or 'p'
                   1213: Will display negative numbers within parentheses instead of showing a minus sign.
                   1214: @item , (comma)
                   1215: Will add commas as thousands separators.
                   1216: @item +
                   1217: Will include a plus sign for positive numbers. Not compatible with 'P' or 'p'.
                   1218: @item -
                   1219: Will remove the minus sign from negative numbers. Not compatible with 'p' or 'P'.
                   1220: @item 't' or 'T'
                   1221: Will place the sign after the number instead of before the number.
1.23      snw      1222: @end table
1.22      snw      1223: 
                   1224: The optional third argument is a number indicating how many digits to which the fractional part of the number will be zero-padded.
1.1       snw      1225: 
                   1226: @node $GET()
                   1227: @section $GET
                   1228: @cindex $GET
                   1229: @cindex intrinsic functions, $GET
                   1230: 
                   1231: Returns the value of a local, global, or SSVN if the specified item is defined, or a default value otherwise.
                   1232: 
                   1233: The first argument is the local, global, or SSVN to be examined.
                   1234: 
                   1235: The optional second argument is the default value to be returned if the referenced item is undefined, and defaults to the empty string.
                   1236: 
                   1237: @node $INSTANCEOF()
                   1238: @section $INSTANCEOF
                   1239: @cindex $INSTANCEOF
                   1240: @cindex intrinsic functions, $INSTANCEOF
                   1241: @cindex object functions, $INSTANCEOF
                   1242: 
                   1243: Returns @code{1} if the specified @emph{lvn} is an instance of class @emph{class}, or @code{0} otherwise.
                   1244: 
                   1245: The first argument is a string representing a valid FreeM local variable.
                   1246: 
                   1247: The second argument is a string representing a valid FreeM class.
                   1248: 
                   1249: @example
1.22      snw      1250: DEFAULT.USER> N STR=$$^%STRING
1.1       snw      1251: 
1.22      snw      1252: DEFAULT.USER> W $INSTANCEOF("STR","^%STRING")
1.1       snw      1253: 1
                   1254: @end example
                   1255: 
                   1256: @node $JUSTIFY()
                   1257: @section $JUSTIFY
                   1258: @cindex $JUSTIFY
                   1259: @cindex intrinsic functions, $JUSTIFY
                   1260: 
                   1261: Right-justifies a string based on a specified fixed length.
                   1262: 
                   1263: The first argument is the source string.
                   1264: 
                   1265: The second argument is the character length of the output.
                   1266: 
                   1267: The optional third argument controls the number of fractional digits to be included in the output, and defaults to the number of digits specified in the first argument.
                   1268: 
                   1269: @node $LENGTH()
                   1270: @section $LENGTH
                   1271: @cindex $LENGTH
                   1272: @cindex intrinsic functions, $LENGTH
                   1273: 
                   1274: Returns the length of a string, or the number of items in a list delimited by a specified character (as used by @code{@ref{$PIECE()}}).
                   1275: 
                   1276: The first argument is the source string.
                   1277: 
                   1278: The optional second argument is the list delimiter to be used. When this argument is omitted, the length of the string in characters is returned.
                   1279: 
                   1280: @node $NAME()
                   1281: @section $NAME
                   1282: @cindex $NAME
                   1283: @cindex intrinsic functions, $NAME
                   1284: 
                   1285: Returns the canonical name reference along with some or all of its subscripts.
                   1286: 
                   1287: The first argument is the source name.
                   1288: 
                   1289: The optional second argument indicates the maximum subscript count to be returned, and defaults to the subscript count of the source name.
                   1290: 
                   1291: @node $NEXT()
                   1292: @section $NEXT
                   1293: @cindex $NEXT
                   1294: @cindex intrinsic functions, $NEXT
                   1295: 
1.25      snw      1296: Deprecated. Use @code{$ORDER} instead.
                   1297: 
1.1       snw      1298: @node $ORDER()
                   1299: @section $ORDER
                   1300: @cindex $ORDER
                   1301: @cindex intrinsic functions, $ORDER
                   1302: 
1.25      snw      1303: Returns the previous subscript or next subscript in a local, global, or a subset of structured system variables.
                   1304: 
                   1305: The first argument is the subscripted local, global, or SSVN.
                   1306: 
                   1307: The optional second argument can be @code{1} to retrieve the next subscript, or @code{-1} to return the previous.
                   1308: 
1.1       snw      1309: @node $PIECE()
                   1310: @section $PIECE
                   1311: @cindex $PIECE
                   1312: @cindex intrinsic functions, $PIECE
                   1313: 
                   1314: @emph{Syntax}
                   1315: 
                   1316: @code{$PIECE(@emph{s},@emph{d}[,@emph{n}[,@emph{end}]])}
                   1317: 
                   1318: Accesses the @code{n}th through @code{end} @code{d}-delimited pieces of string @code{s}.
                   1319: 
                   1320: The first argument is the string to be evaluated.
                   1321: 
                   1322: The second argument is the delimiter to be used.
                   1323: 
                   1324: The optional third argument is the first @code{d}-delimited piece to access, and defaults to @code{1}.
                   1325: 
                   1326: The optional fourth argument is the final @code{d}-delimited piece to access, and defaults to the value of the third argument (@code{n}).
                   1327: 
                   1328: Can be used on the left-hand side of an expression in order to @code{@ref{SET}} a value into a @code{d}-delimited piece of @code{s}, as in:
                   1329: 
                   1330: @example
1.28      snw      1331: ; ^snw="this^is^a^piece"
                   1332: SET $PIECE(^snw,"^",2)="isn't" ; => "this^isn't^a^piece"
1.1       snw      1333: @end example
                   1334: 
                   1335: @node $QLENGTH()
                   1336: @section $QLENGTH
                   1337: @cindex $QLENGTH
                   1338: @cindex intrinsic functions, $QLENGTH
                   1339: 
                   1340: @emph{Syntax}
                   1341: 
                   1342: @example
                   1343: @code{$QLENGTH(@emph{expr V glvn})}
                   1344: @end example
                   1345: 
                   1346: Returns the number of subscripts in @emph{glvn}.
                   1347: 
                   1348: @emph{Example}
                   1349: @example
                   1350: @code{SET SUBCT=$QLENGTH("^GBL(1,2,3)") ; => 3}
                   1351: @end example
                   1352: 
                   1353: @node $QSUBSCRIPT()
                   1354: @section $QSUBSCRIPT
                   1355: @cindex $QSUBSCRIPT
                   1356: @cindex intrinsic functions, $QSUBSCRIPT
                   1357: 
                   1358: @emph{Syntax}
                   1359: 
                   1360: @example
                   1361: @code{$QSUBSCRIPT(@emph{expr V glvn},@emph{expr V n})}
                   1362: @end example
                   1363: 
1.28      snw      1364: In the RHS form, returns the @emph{n}th subscript of @emph{glvn}.
1.1       snw      1365: 
                   1366: @emph{Example}
                   1367: 
                   1368: @example
                   1369: @code{SET SUB=$QSUBSCRIPT("^GBL(1,2,3)",2) ; => 2}
                   1370: @end example
                   1371: 
1.28      snw      1372: @emph{Syntax}
                   1373: 
                   1374: @example
                   1375: @code{SET $QSUBSCRIPT(@emph{expr V glvn},@emph{expr V n})=@emph{expr} ; => ^GBL(1,4,3)}
                   1376: @end example
                   1377: 
                   1378: In the LHS form, sets the @emph{n}th subscript of @emph{glvn} to @emph{expr}.
                   1379: 
1.1       snw      1380: @node $QUERY()
                   1381: @section $QUERY
                   1382: @cindex $QUERY
                   1383: @cindex intrinsic functions, $QUERY
                   1384: 
                   1385: Returns the next subscripted reference in a global.
                   1386: 
                   1387: @emph{Syntax}
                   1388: 
                   1389: @example
                   1390: @code{$QUERY(@emph{glvn})}
                   1391: @end example
                   1392: 
                   1393: @emph{Example}
                   1394: 
                   1395: We will assume the following data structure exists:
                   1396: @example
1.28      snw      1397: ^snw(1)=1
                   1398: ^snw(1,2)="foo"
                   1399: ^snw(2)=3
                   1400: ^snw(3)=""
1.1       snw      1401: @end example
                   1402: 
1.28      snw      1403: The following code will retrieve the next subscripted name after @code{^snw(1)}:
1.1       snw      1404: 
                   1405: @example
1.28      snw      1406: @code{SET NEXTNAM=$QUERY(^snw(1)) ; => ^snw(1,2)}
1.1       snw      1407: @end example
                   1408: 
                   1409: @node $RANDOM()
                   1410: @section $RANDOM
                   1411: @cindex $RANDOM
                   1412: @cindex intrinsic functions, $RANDOM
                   1413: 
                   1414: @emph{Syntax}
                   1415: 
                   1416: @example
                   1417: $RANDOM(@emph{max})
                   1418: @end example
                   1419: 
                   1420: Returns a pseudo-random integer in the range of @code{0..@emph{max} - 1} 
                   1421: 
                   1422: @node $REVERSE()
                   1423: @section $REVERSE
                   1424: @cindex $REVERSE
                   1425: @cindex intrinsic functions, $REVERSE
                   1426: 
                   1427: @emph{Syntax}
                   1428: 
                   1429: @example
                   1430: $REVERSE(@emph{s})
                   1431: @end example
                   1432: 
                   1433: Returns the reverse of string @emph{s}.
                   1434: 
                   1435: @emph{Example}
                   1436: 
                   1437: @example
                   1438: SET FOO=$REVERSE("ABC") ; => CBA
                   1439: @end example
                   1440: 
                   1441: @node $SELECT()
                   1442: @section $SELECT
                   1443: @cindex $SELECT
                   1444: @cindex intrinsic functions, $SELECT
                   1445: 
                   1446: Returns a value corresponding to the first true condition in a list of conditional expressions. Each argument is an expression, followed by a colon, followed by an expression whose value will be returned if the first expression is true. If no expressions are true, error condition @code{M4} is raised.
                   1447: 
                   1448: @emph{Example}
                   1449: 
                   1450: @example
                   1451: SET FOO=$SELECT(1=2:"math is broken",1=1:"the world makes sense") ; => "the world makes sense"
                   1452: @end example
                   1453: 
                   1454: @node $STACK()
                   1455: @section $STACK
                   1456: @cindex $STACK
                   1457: @cindex intrinsic functions, $STACK
                   1458: 
                   1459: Returns information about the program execution stack. The @code{$STACK} intrinsic function has both a one-argument form and a two-argument form.
                   1460: 
                   1461: @emph{Syntax (One-Argument)}
                   1462: 
                   1463: @example
                   1464:  $STACK(@emph{<num>})
                   1465: @end example
                   1466: 
                   1467: If @emph{num} is @code{0}, returns the command with which this FreeM instance was invoked.
                   1468: 
                   1469: If @emph{num} is @code{-1}, returns the current program execution stack level.
                   1470: 
                   1471: If @emph{num} represents a valid program execution stack depth above @code{0}, returns one of the following values indicating the reason for which the referenced program execution stack level was created:
                   1472: 
                   1473: @table @asis
                   1474: 
                   1475: @item @code{$$}
                   1476: If @code{$STACK(@emph{<num>})="$$"}, program execution stack level @code{num} was created as the result of an extrinsic function call
                   1477: 
                   1478: @item @emph{<m-command>}
                   1479: If @code{$STACK(@emph{<num>})} returns a valid M command, the referenced program execution stack level was created as a result of the @emph{m-command} command.
                   1480: 
                   1481: @end table
                   1482: 
                   1483: @emph{Syntax (Two-Argument})
                   1484: 
                   1485: @example
                   1486:  $STACK(@emph{<num>},"[ECODE|MCODE|PLACE]")
                   1487: @end example
                   1488: 
                   1489: Returns the error codes, M program code, or entryref applicable to the action that created program execution stack level @emph{num}.
                   1490: 
                   1491: @node $TEXT()
                   1492: @section $TEXT
                   1493: @cindex $TEXT
                   1494: @cindex intrinsic functions, $TEXT
                   1495: 
                   1496: Returns a line of code from a routine.
                   1497: 
                   1498: @node $TRANSLATE()
                   1499: @section $TRANSLATE
                   1500: @cindex $TRANSLATE
                   1501: @cindex intrinsic functions, $TRANSLATE
                   1502: 
1.25      snw      1503: Replaces characters in a string.
                   1504: 
                   1505: The first argument is a string expression representing the text to be changed.
                   1506: 
                   1507: The second argument is a list of characters to replace.
                   1508: 
                   1509: The third argument is a list of characters to use as the replacements for the characters in the second argument.
                   1510: 
                   1511: @emph{Example}
                   1512: 
                   1513: @example
                   1514:  DEFAULT.USER> W $TRANSLATE("twig","wt","rb")
                   1515:  brig
                   1516: @end example
                   1517: 
1.1       snw      1518: @node $TYPE()
                   1519: @section $TYPE
                   1520: @cindex $TYPE
                   1521: @cindex intrinsic functions, $TYPE
                   1522: @cindex object functions, $TYPE
                   1523: 
                   1524: Returns a string giving the class of the object specified in the parameter.
                   1525: 
                   1526: @xref{Object-Oriented Programming}
                   1527: 
                   1528: @node $VIEW()
                   1529: @section $VIEW
                   1530: @cindex $VIEW
                   1531: @cindex intrinsic functions, $VIEW
                   1532: 
                   1533: @node $ZBOOLEAN()
                   1534: @section $ZBOOLEAN
                   1535: @cindex $ZBOOLEAN
                   1536: @cindex intrinsic functions, $ZBOOLEAN
                   1537: @cindex intrinsic functions, implementation-specific
                   1538: 
                   1539: 
                   1540: Performs @emph{boolean-operation} on numeric arguments @emph{A} and @emph{B}.
                   1541: 
                   1542: @emph{Syntax}
                   1543: 
                   1544: @example
                   1545: SET RESULT=$ZBOOLEAN(@emph{A},@emph{B},@emph{boolean-operation})
                   1546: @end example
                   1547: 
                   1548: @code{$ZBOOLEAN} Operations (@emph{boolean-operation} values)
                   1549: 
                   1550: @table @code
                   1551: @item 0
                   1552: Always @emph{false}
                   1553: @item 1
                   1554: @code{A AND B}
                   1555: @item 2
                   1556: @code{A AND NOT B}
                   1557: @item 3
                   1558: @code{A}
                   1559: @item 4
                   1560: @code{NOT A AND B}
                   1561: @item 5
                   1562: @code{B}
                   1563: @item 6
                   1564: @code{A XOR B}
                   1565: @item 7
                   1566: @code{A OR B}
                   1567: @item 8
                   1568: @code{A NOR B}
                   1569: @item 9
                   1570: @code{A EQUALS B}
                   1571: @item 10
                   1572: @code{NOT B}
                   1573: @item 11
                   1574: @code{A OR NOT B}
                   1575: @item 12
                   1576: @code{NOT A}
                   1577: @item 13
                   1578: @code{NOT A OR B}
                   1579: @item 14
                   1580: @code{A NAND B}
                   1581: @item 15
                   1582: Always @emph{true}
                   1583: @end table
                   1584: 
                   1585: @node $ZCALL()
                   1586: @section $ZCALL
                   1587: @cindex $ZCALL
                   1588: @cindex intrinsic functions, $ZCALL
                   1589: @cindex intrinsic functions, implementation-specific
                   1590: 
1.26      snw      1591: Purpose unknown.
                   1592: 
1.1       snw      1593: @node $ZCRC()
                   1594: @section $ZCRC
                   1595: @cindex $ZCRC
                   1596: @cindex intrinsic functions, $ZCRC
                   1597: @cindex intrinsic functions, implementation-specific
                   1598: 
                   1599: Returns a checksum of @code{arg1}.
                   1600: 
                   1601: @emph{Syntax}
                   1602: 
                   1603: @code{$ZCRC(@emph{arg1})}
                   1604: 
                   1605: @code{SET VAR=$ZCRC("MUMPS") ; => 86}
                   1606: 
                   1607: @node $ZDATA()
                   1608: @section $ZDATA
                   1609: @cindex $ZDATA
                   1610: @cindex intrinsic functions, $ZDATA
                   1611: @cindex intrinsic functions, implementation-specific
                   1612: 
1.26      snw      1613: Purpose unknown.
                   1614: 
1.1       snw      1615: @node $ZDATE()
                   1616: @section $ZDATE
                   1617: @cindex $ZDATE
                   1618: @cindex intrinsic functions, $ZDATE
                   1619: @cindex intrinsic functions, implementation-specific
                   1620: 
                   1621: Converts a @code{@ref{$HOROLOG}} string into a human-readable date.
                   1622: 
                   1623: @emph{Syntax}
                   1624: 
                   1625: @example
                   1626: SET VAR=$ZDATE($H[,@emph{<format-string>}])
                   1627: @end example
                   1628: 
                   1629: The optional @emph{<format-string>} follows the same rules as the UNIX @code{strftime} function. If @emph{<format-string>} is omitted, the value of @code{^$SYSTEM("ZDATE_FORMAT")} is used (typically @code{%x}).
                   1630: 
                   1631: @xref{^$SYSTEM}
                   1632: 
                   1633: @node $ZEDIT()
                   1634: @section $ZEDIT
                   1635: @cindex $ZEDIT
                   1636: @cindex intrinsic functions, $ZEDIT
                   1637: @cindex intrinsic functions, implementation-specific
                   1638: 
1.26      snw      1639: Purpose unknown.
                   1640: 
1.1       snw      1641: @node $ZHOROLOG()
                   1642: @section $ZHOROLOG
                   1643: @cindex $ZHOROLOG
                   1644: @cindex intrinsic functions, $ZHOROLOG
                   1645: @cindex intrinsic functions, implementation-specific
                   1646: 
                   1647: Converts date and/or time values producible by @code{@ref{$ZDATE()}} or @code{@ref{$ZTIME()}} to @code{@ref{$HOROLOG}} format.
                   1648: 
                   1649: @emph{Syntax}
                   1650: 
                   1651: @example
                   1652: $ZHOROLOG(@emph{<date-value>},@emph{<format-string>})
                   1653: @end example
                   1654: 
                   1655: @emph{<date-value>} is a date or time string compatible with the formats from @code{@ref{$ZDATE()}} or @code{@ref{$ZTIME}}.
                   1656: 
                   1657: @emph{<format-string>} is a format string of the same format as used by the @code{strptime(3)} UNIX function.
                   1658: 
                   1659: @node $ZKEY()
                   1660: @section $ZKEY
                   1661: @cindex $ZKEY
                   1662: @cindex intrinsic functions, $ZKEY
                   1663: @cindex intrinsic functions, implementation-specific
                   1664: 
1.26      snw      1665: Purpose unknown.
                   1666: 
1.1       snw      1667: @node $ZLENGTH()
                   1668: @section $ZLENGTH
                   1669: @cindex $ZLENGTH
                   1670: @cindex intrinsic functions, $ZLENGTH
                   1671: @cindex intrinsic functions, implementation-specific
                   1672: 
1.26      snw      1673: Purpose unknown.
                   1674: 
1.1       snw      1675: @node $ZLSD()
                   1676: @section $ZLSD
                   1677: @cindex $ZLSD
                   1678: @cindex intrinsic functions, $ZLSD
                   1679: @cindex intrinsic functions, implementation-specific
                   1680: 
                   1681: Returns the Levenshtein distance between two arguments. The Levenshtein distance represents the minimum number of edits needed to change the first argument into the second argument.
                   1682: 
                   1683: @emph{Syntax}
                   1684: 
                   1685: @code{SET VAR=$ZLSD(@emph{arg1},@emph{arg2})}
                   1686: 
                   1687: @emph{Example}
                   1688: 
                   1689: @code{SET VAR=$ZLSD("KITTENS","MITTENS") ; => 1}
                   1690: 
                   1691: @node $ZM()
                   1692: @section $ZM
                   1693: @cindex $ZM
                   1694: @cindex intrinsic functions, $ZM
                   1695: @cindex intrinsic functions, implementation-specific
                   1696: 
                   1697: @node $ZNAME()
                   1698: @section $ZNAME
                   1699: @cindex $ZNAME
                   1700: @cindex intrinsic functions, $ZNAME
                   1701: @cindex intrinsic functions, implementation-specific
                   1702: 
1.26      snw      1703: Purpose unknown.
                   1704: 
1.1       snw      1705: @node $ZNEXT()
                   1706: @section $ZNEXT
                   1707: @cindex $ZNEXT
                   1708: @cindex intrinsic functions, $ZNEXT
                   1709: @cindex intrinsic functions, implementation-specific
                   1710: 
1.26      snw      1711: Purpose unknown.
                   1712: 
1.1       snw      1713: @node $ZORDER()
                   1714: @section $ZORDER
                   1715: @cindex $ZORDER
                   1716: @cindex intrinsic functions, $ZORDER
                   1717: @cindex intrinsic functions, implementation-specific
                   1718: 
1.26      snw      1719: Purpose unknown.
                   1720: 
1.1       snw      1721: @node $ZPIECE()
                   1722: @section $ZPIECE
                   1723: @cindex $ZPIECE
                   1724: @cindex intrinsic functions, $ZPIECE
                   1725: @cindex intrinsic functions, implementation-specific
                   1726: 
1.26      snw      1727: Purpose unknown.
                   1728: 
1.1       snw      1729: @node $ZPREVIOUS()
                   1730: @section $ZPREVIOUS
                   1731: @cindex $ZPREVIOUS
                   1732: @cindex intrinsic functions, $ZPREVIOUS
                   1733: @cindex intrinsic functions, implementation-specific
                   1734: 
1.26      snw      1735: Purpose unknown.
                   1736: 
1.1       snw      1737: @node $ZREPLACE()
                   1738: @section $ZREPLACE
                   1739: @cindex $ZREPLACE
                   1740: @cindex intrinsic functions, $ZREPLACE
                   1741: @cindex intrinsic functions, implementation-specific
                   1742: 
                   1743: Replaces all instances of @code{arg2} with @code{arg3} in string @code{arg1}.
                   1744: 
                   1745: @emph{Syntax}
                   1746: @code{$ZREPLACE(@emph{arg1},@emph{arg2},@emph{arg3})}
                   1747: 
                   1748: @emph{Example}
                   1749: 
                   1750: @code{SET VAR=$ZREPLACE("CAT","C","B") ; => BAT}
                   1751: 
                   1752: @node $ZSYNTAX()
                   1753: @section $ZSYNTAX
                   1754: @cindex $ZSYNTAX
                   1755: @cindex intrinsic functions, $ZSYNTAX
                   1756: @cindex intrinsic functions, implementation-specific
                   1757: 
                   1758: @code{$ZSYNTAX} performs a very basic syntax check on @emph{expr V mcode}. Checks only for illegal commands, mismatched brackets, mismatched quotes, missing or surplus arguments, or surplus commas.
                   1759: 
                   1760: @emph{Syntax}
                   1761: @example
                   1762: $ZSYNTAX(@emph{expr V mcode})
                   1763: @end example
                   1764: 
                   1765: If no syntax error is found, returns the empty string.
                   1766: 
                   1767: If a syntax error is found, returns a number indicating the position in @emph{expr V mcode} at which the error was found, followed by a comma, and the FreeM error code that was found.
                   1768: 
                   1769: @node $ZTIME()
                   1770: @section $ZTIME
                   1771: @cindex $ZTIME
                   1772: @cindex intrinsic functions, $ZTIME
                   1773: @cindex intrinsic functions, implementation-specific
                   1774: 
                   1775: Converts a @code{@ref{$HOROLOG}} string into a human-readable time.
                   1776: 
                   1777: @emph{Syntax}
                   1778: 
                   1779: @example
                   1780: SET VAR=$ZTIME($H[,@emph{<format-string>}])
                   1781: @end example
                   1782: 
                   1783: The optional @emph{<format-string>} follows the same rules as the UNIX @code{strftime(3)} function. If @emph{<format-string>} is omitted, the value of @code{^$SYSTEM("ZTIME_FORMAT")} is used (typically @code{%X}).
                   1784: 
                   1785: @node OBJECT Methods
                   1786: @chapter OBJECT Methods
                   1787: 
                   1788: These methods are part of the @code{^%OBJECT} class, from which all FreeM objects ultimately inherit.
                   1789: 
                   1790: Please note that classes may override @code{^%OBJECT} methods (or methods of any class) in order to provide results more fitting to the class's abstraction goals.
                   1791: 
                   1792: @menu
                   1793: * $$TONUMBER::          Returns the canonical numeric representation of the object.
                   1794: * $$TYPE::              Returns the fully-qualified class name of the object.
                   1795: * $$VALUE::             Returns the value of the object.
                   1796: @end menu
                   1797: 
                   1798: @node $$TONUMBER
                   1799: @section $$TONUMBER
                   1800: 
                   1801: Returns (when applicable) a canonical numeric representation of the referenced object.
                   1802: 
                   1803: @emph{Syntax}
                   1804: 
                   1805: @example
                   1806: W $$MYOBJECT.TONUMBER(),!
                   1807: @end example
                   1808: 
                   1809: If no canonical numeric representation of the object is possible, will return the empty string.
                   1810: 
                   1811: @node $$TYPE
                   1812: @section $$TYPE
                   1813: 
                   1814: Returns the fully-qualified class of the referenced object.
                   1815: 
                   1816: @emph{Syntax}
                   1817: 
                   1818: @example
                   1819: W $$MYOBJECT.TYPE()
                   1820: @end example
                   1821: 
                   1822: Note that M variables that are created by non-object-oriented means will be objects of the @code{^%STRING} class.
                   1823: 
                   1824: @node $$VALUE
                   1825: @section $$VALUE
                   1826: 
                   1827: Returns the value of the referenced object.
                   1828: 
                   1829: @emph{Syntax}
                   1830: 
                   1831: @example
                   1832: W $$MYOBJECT.VALUE()
                   1833: @end example
                   1834: 
                   1835: @node STRING Methods
                   1836: @chapter STRING Methods
                   1837: 
                   1838: These are methods inherent to the @code{^%STRING} class, which is the default class for M variables created without specifying a class.
                   1839: 
                   1840: @menu
                   1841: * $$ASCII::             Return the ASCII code of a character within the string.
                   1842: * $$DATA::              Return tree characteristics of the string.
                   1843: * $$DISTANCE::          Determine Levenstein distance between this string and another.
                   1844: * $$EXTRACT::           Return a substring of the string.
                   1845: * $$FIND::              Find the position of a substring within the string.
                   1846: * $$FNUMBER::           Format numbers.
                   1847: * $$JUSTIFY::           Pad the string to specific positions.
                   1848: * $$LENGTH::            Return the length of the string.
                   1849: * $$PIECECOUNT::        Return the count of pieces existing between instances of a delimiter.
                   1850: * $$PIECE::             Return a delimited subset of the string.
                   1851: * $$REPLACE::           Replace instances of a substring within the string.
                   1852: * $$REVERSE::           Reverse the order of characters in the string.
                   1853: * $$TOLOWER::           Return a lowercase version of the string.
                   1854: * $$TOUPPER::           Return an uppercase version of the string.
                   1855: * $$TRANSLATE::         Replace individual characters within the string.
                   1856: @end menu
                   1857: 
                   1858: @node $$ASCII
                   1859: @section $$ASCII
                   1860: 
                   1861: Returns the ASCII code of a character within the string. See @ref{$ASCII()}.
                   1862: 
                   1863: @emph{Syntax}
                   1864: 
                   1865: @example
                   1866: W $$MYOBJECT.ASCII(3)
                   1867: @end example
                   1868: 
                   1869: The above example returns the ASCII code in position 3 of string object @code{MYOBJECT}.
                   1870: 
                   1871: @node $$DATA
                   1872: @section $$DATA
                   1873: 
                   1874: Returns the value of the @code{$DATA} intrinsic function as performed on the value of the object. See @ref{$DATA()}.
                   1875: 
                   1876: @emph{Syntax}
                   1877: 
                   1878: @example
                   1879: W $$MYOBJECT.DATA()
                   1880: @end example
                   1881: 
                   1882: @node $$DISTANCE
                   1883: @section $$DISTANCE
                   1884: 
                   1885: Returns the Levenstein distance between the string and another string. See @ref{$ZLSD()}.
                   1886: 
                   1887: @emph{Syntax}
                   1888: 
                   1889: @example
                   1890: W $$MYOBJECT.DISTANCE("someString")
                   1891: @end example
                   1892: 
                   1893: @node $$EXTRACT
                   1894: @section $$EXTRACT
                   1895: 
                   1896: Returns a substring of the string. See @ref{$EXTRACT()}.
                   1897: 
                   1898: @emph{Syntax}
                   1899: 
                   1900: @example
                   1901: $$<objectName>.EXTRACT(<start>,<end>)
                   1902: @end example
                   1903: 
                   1904: 
                   1905: @node $$FIND
                   1906: @section $$FIND
                   1907: 
1.25      snw      1908: Finds the character immediately following the first occurence of a substring within a string.
                   1909: 
                   1910: The first argument is the substring to be located.
                   1911: 
                   1912: The second argument is the position within the string at which to begin searching.
                   1913: 
                   1914: See @ref{$FIND()}.
                   1915: 
1.1       snw      1916: @node $$FNUMBER
                   1917: @section $$FNUMBER
                   1918: 
1.25      snw      1919: Formats a number according to a set of formatting codes.
                   1920: 
                   1921: The argument is a series of formatting codes. See @ref{$FNUMBER()} for details.
                   1922: 
1.1       snw      1923: @node $$JUSTIFY
                   1924: @section $$JUSTIFY
                   1925: 
1.25      snw      1926: Right-justifies a string based on a specified fixed length.
                   1927: 
                   1928: The first argument is the character length of the output.
                   1929: 
                   1930: The second argument controls the number of fractional digits to be included in the output, and defaults to the number of digits specified in the first argument.
                   1931: 
                   1932: See @ref{$JUSTIFY()} for details.
                   1933: 
1.1       snw      1934: @node $$LENGTH
                   1935: @section $$LENGTH
                   1936: 
1.25      snw      1937: Returns the length of the string.
                   1938: 
1.1       snw      1939: @node $$PIECECOUNT
                   1940: @section $$PIECECOUNT
                   1941: 
1.25      snw      1942: Returns the number of items in a list delimited by the character specified in the argument.
                   1943: 
1.1       snw      1944: @node $$PIECE
                   1945: @section $$PIECE
                   1946: 
1.25      snw      1947: @emph{Syntax}
                   1948: 
                   1949: @code{$PIECE(@emph{d}[,@emph{n}[,@emph{end}]])}
                   1950: 
                   1951: Accesses the @code{n}th through @code{end} @code{d}-delimited pieces of the string.
                   1952: 
                   1953: The first argument is the delimiter to be used.
                   1954: 
                   1955: The optional second argument is the first @code{d}-delimited piece to access, and defaults to @code{1}.
                   1956: 
                   1957: The optional third argument is the final @code{d}-delimited piece to access, and defaults to the value of the third argument (@code{n}).
                   1958: 
                   1959: 
1.1       snw      1960: @node $$REPLACE
                   1961: @section $$REPLACE
                   1962: 
1.25      snw      1963: @emph{Syntax}
                   1964: @code{myString.$$REPLACE(@emph{arg1},@emph{arg2})}
                   1965: 
                   1966: Replaces all instances of @code{arg2} with @code{arg3} in @code{myString}.
                   1967: 
1.1       snw      1968: @node $$REVERSE
                   1969: @section $$REVERSE
                   1970: 
1.25      snw      1971: Returns the reverse of the string.
                   1972: 
1.1       snw      1973: @node $$TOLOWER
                   1974: @section $$TOLOWER
                   1975: 
1.25      snw      1976: Returns an all-lowercase version of the string.
                   1977: 
1.1       snw      1978: @node $$TOUPPER
                   1979: @section $$TOUPPER
                   1980: 
1.25      snw      1981: Returns an all-uppercase version of the string.
                   1982: 
1.1       snw      1983: @node $$TRANSLATE
                   1984: @section $$TRANSLATE
                   1985: 
1.25      snw      1986: Identical to @ref{$TRANSLATE()}, except that the arguments are shifted left by one, and the input string is implicit (the object).
                   1987: 
1.1       snw      1988: @node Commands
                   1989: @chapter Commands
                   1990: @cindex commands
                   1991: 
                   1992: @menu
                   1993: * @@::                                  Execute the following expression as M code.
                   1994: * !::                                   Run an external program or command.
                   1995: * !!::                                  Launch a subshell from FreeM direct mode.
                   1996: * ABLOCK::                              Increment the block counter for one or more event classes.
                   1997: * ASSERT::                              Raise error when a conditional expression evaluates @emph{false}.
                   1998: * ASTART::                              Enable asynchronous event handling for one or more event classes.
                   1999: * ASTOP::                               Disable asynchronous event handling for one or more event classes.
                   2000: * AUNBLOCK::                            Decrement the block counter for one or more event classes.
                   2001: * BREAK::                               Interrupt a running routine to allow interactive debugging.
                   2002: * CLOSE::                               Close an input/output device.
                   2003: * CONST::                               Define a constant that cannot be altered after initial definition.
                   2004: * DO::                                  Transfer program control to one or more subroutines or introduces a new execution level.
                   2005: * ELSE::                                Execute the remainder of a line if @code{@ref{$TEST}} evaluates @emph{false}.
                   2006: * FOR::                                 Repeat execution of a line or block of code.
                   2007: * GOTO::                                Unconditionally transfer program execution to a supplied @emph{entryref}.
                   2008: * HALT::                                Terminate the current FreeM interpreter instance.
                   2009: * HANG::                                Temporarily suspend the running program.
                   2010: * IF::                                  Execute the remainder of a line if a conditional expression evaluates @emph{true}.
                   2011: * JOB::                                 Execute an @emph{entryref} in a child process.
                   2012: * KILL::                                Remove data from a local, global, or structured system variable.
                   2013: * KSUBSCRIPTS::                         Kill only the descendant subscripts of a local, global, global, or structured system variable.
                   2014: * KVALUE::                              Kill only the value of a local, global, or structured system variable.
                   2015: * LOCK::                                Control advisory locking for concurrency control.
                   2016: * MAP::                                 Map a global name to a non-default namespace.
                   2017: * MERGE::                               Merge contents of one local, global, or structured system variable into another.
                   2018: * NEW::                                 Introduce a new scope for a specified local variable or intrinsic special variable or instantiate an object.
                   2019: * OPEN::                                Open a sequential or socket input/output device.
                   2020: * QUIT::                                End execution of the current process level, optionally with return value.
                   2021: * READ::                                Read input from an input/output device.
                   2022: * SET::                                 Set the value of a local variable, global, intrinsic special variable, or structured system variable.
                   2023: * TCOMMIT::                             Commit a transaction.
                   2024: * THEN::                                Preserve @code{@ref{$TEST}} until the end of the current line.
                   2025: * THROW::                               Programmatically raise an error condition.
                   2026: * TROLLBACK::                           Roll back all pending transactions.
                   2027: * TSTART::                              Introduce a new transaction processing level.
                   2028: * UNMAP::                               Remove a mapping of a global to a non-default namespace.
                   2029: * USE::                                 Set the currently-active input/output device.
                   2030: * VIEW::                                Modify FreeM internal parameters.
                   2031: * WATCH::                               Enable or disable watchpoints, or set or clear watchpoints on specified globals, locals, or structured system variables.
                   2032: * WITH::                                Set prefix for future variable references.
                   2033: * WRITE::                               Write output to current input/output device.
                   2034: * XECUTE::                              Interpret string as M code.
                   2035: * ZBREAK::                              Unknown.
                   2036: * ZGO::                                 Unknown.
                   2037: * ZHALT::                               Unknown.
                   2038: * ZINSERT::                             Insert code into routine buffer.
                   2039: * ZJOB::                                Unknown.
                   2040: * ZLOAD::                               Load routine into routine buffer.
                   2041: * ZNEW::                                Unknown.
                   2042: * ZPRINT::                              Print contents of routine buffer.
                   2043: * ZQUIT::                               Unknown.
                   2044: * ZREMOVE::                             Remove code from routine buffer.
                   2045: * ZSAVE::                               Save routine buffer to disk.
                   2046: * ZTRAP::                               Unknown.
                   2047: * ZWRITE::                              Write local variable, global, or structured system variable to @code{@ref{$IO}}.
                   2048: @end menu
                   2049: 
                   2050: @node @@
                   2051: @section @@
                   2052: @cindex @@
                   2053: @cindex commands, @@
                   2054: @cindex commands, implementation-specific
                   2055: @cindex commands, non-standard
                   2056: 
                   2057: Executes FreeM code @emph{expr V mcode}.
                   2058: 
                   2059: @emph{Syntax}
                   2060: 
                   2061: @example
                   2062: @@@emph{expr V mcode}
                   2063: @end example
                   2064: 
                   2065: @emph{Example (Using Variable)}
                   2066: 
                   2067: @example
1.22      snw      2068: DEFAULT.USER> SET FOO="WRITE ""HELLO WORLD"",!"
                   2069: DEFAULT.USER> @@FOO
1.1       snw      2070: 
                   2071: HELLO WORLD
                   2072: 
1.22      snw      2073: DEFAULT.USER>
1.1       snw      2074: @end example
                   2075: 
                   2076: @emph{Example (Using String Literal)}
                   2077: 
                   2078: @example
1.22      snw      2079: DEFAULT.USER> @@"WRITE ""HELLO WORLD"",!"
1.1       snw      2080: 
                   2081: HELLO WORLD
                   2082: 
1.22      snw      2083: DEFAULT.USER>
1.1       snw      2084: @end example
                   2085: 
                   2086: @emph{Example (Using Indirection)}
                   2087: 
                   2088: @example
1.22      snw      2089: DEFAULT.USER> SET FOO="BAR"
1.1       snw      2090: 
1.22      snw      2091: DEFAULT.USER> SET BAR="WRITE ""HELLO WORLD"",!"
1.1       snw      2092: 
1.22      snw      2093: DEFAULT.USER> @@@@FOO
1.1       snw      2094: 
                   2095: HELLO WORLD
                   2096: 
1.22      snw      2097: DEFAULT.USER>
1.1       snw      2098: @end example
                   2099: 
                   2100: 
                   2101: @node !
                   2102: @section !
                   2103: @cindex !
                   2104: @cindex commands, !
                   2105: @cindex commands, external
                   2106: @cindex commands, non-standard
                   2107: @emph{FreeM Extension}
                   2108: 
                   2109: Invokes a shell to run @emph{<external-command>} from within FreeM. This temporarily disables @command{SIGALRM} handling in FreeM, which may interrupt the use of event-driven M programming commands including @command{ESTART} and @command{ESTOP}.
                   2110: 
                   2111: If the @command{<} character is supplied immediately preceding @emph{<external-command>}, FreeM will append the contents of M local variable @code{%} to @emph{<external-command>} as standard input.
                   2112: 
                   2113: If the @command{>} character is supplied immediately preceding @emph{<external-command>}, FreeM will take the standard output stream of @emph{<external-command>} and store it in M local variable @code{%}.
                   2114: 
                   2115: @code{%} contains the number of lines in the input or output. @code{%(1)..%(@emph{n})} contains the data for lines 1-@emph{n}.
                   2116: 
                   2117: @node !!
                   2118: @section !!
                   2119: @cindex !!
                   2120: @cindex commands, !!
                   2121: @cindex commands, external
                   2122: @cindex commands, non-standard
                   2123: @emph{FreeM Extension}
                   2124: 
                   2125: Launches a subshell within the FreeM direct mode, allowing the user to run operating system commands.
                   2126: 
                   2127: @example
1.22      snw      2128: DEFAULT.USER> !!
1.1       snw      2129: 
                   2130: Type Ctrl-D to exit from the shell
                   2131: $ uname -a
                   2132: Linux hesperos 4.19.0-17-amd64 #1 SMP Debian 4.19.194-3 (2021-07-18) x86_64 GNU/Linux
                   2133: $ exit
                   2134: 
1.22      snw      2135: DEFAULT.USER> 
1.1       snw      2136: @end example
                   2137: 
                   2138: 
                   2139: @node ABLOCK
                   2140: @section ABLOCK
                   2141: @cindex ABLOCK
                   2142: @cindex commands, ABLOCK
                   2143: 
                   2144: Increments the event block counter for one or more event classes. While the block counter for an event class is greater than zero, registered event handlers for that event class will not execute, and will instead be queued for later execution once the block counter reaches zero (all blocks removed).
                   2145: 
                   2146: An implicit @code{ABLOCK} on all event classes occurs when an event handler subroutine is executing. As soon as a @code{QUIT} is reached within an event handler, an implicit @code{ABLOCK} will occur.
                   2147: 
                   2148: @emph{Syntax}
                   2149: 
                   2150: @example
                   2151:   ABLOCK@emph{:postcondition}
                   2152: @end example
                   2153: 
                   2154: In its argumentless form, @code{ABLOCK} increments the block counter for @emph{all} event classes, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2155: 
                   2156: @example
                   2157:   ABLOCK@emph{:postcondition} @emph{evclass1}...,@emph{evclassN}
                   2158: @end example
                   2159: 
                   2160: In its inclusive form, @code{ABLOCK} increments the block counters for all event classes named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2161: 
                   2162: @example
                   2163:   ABLOCK@emph{:postcondition} (@emph{evclass1}...,@emph{evclassN}
                   2164: @end example
                   2165: 
                   2166: In its exclusive form, @code{ABLOCK} increments the block counters for all event classes @emph{except for} those named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2167: 
                   2168: @node ASSERT
                   2169: @section ASSERT
                   2170: @cindex ASSERT
                   2171: @cindex commands, ASSERT
                   2172: @cindex commands, debugging
                   2173: @cindex commands, implementation-specific
                   2174: @cindex commands, non-standard
                   2175: @emph{FreeM Extension}
                   2176: 
                   2177: Triggers error @code{ASSERT} if the supplied truth-valued expression @emph{tvexpr} is @emph{false} (@emph{1} is @emph{true}, and @emph{0} is @emph{false}), and that the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2178: 
                   2179: The @code{ASSERT} error is catchable whether using standard-style, FreeM-style, or DSM 2.0-style error processing.
                   2180: 
                   2181: @emph{Syntax}
                   2182: 
                   2183: @example
                   2184:  ASSERT@emph{:postcondition} @emph{<tvexpr>}
                   2185: @end example
                   2186: 
                   2187: @emph{Example}
                   2188: 
                   2189: @example
1.22      snw      2190: DEFAULT.USER> SET DEBUG=1
1.1       snw      2191: 
                   2192: 
1.22      snw      2193: DEFAULT.USER> ASSERT:DEBUG 1=1
1.1       snw      2194: 
                   2195: 
1.22      snw      2196: DEFAULT.USER> ASSERT:DEBUG 1=0
1.1       snw      2197:  
                   2198:  
                   2199: >> Error ZASSERT:  programmer assertion failed in SYSTEM::^%SYSINIT  [$STACK = 0]
                   2200: >> ASSERT:DEBUG 1=0
                   2201:                    ^
                   2202: @end example
                   2203: 
                   2204: @node ASTART
                   2205: @section ASTART
                   2206: @cindex ASTART
                   2207: @cindex commands, ASTART
                   2208: 
                   2209: Enables asynchronous event handling for one or more event classes.
                   2210: 
                   2211: @emph{Syntax}
                   2212: 
                   2213: @example
                   2214:   ASTART@emph{:postcondition}
                   2215: @end example
                   2216: 
                   2217: In its argumentless form, @code{ASTART} enables asynchronous event handling for all event classes, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2218: 
                   2219: @example
                   2220:   ASTART@emph{:postcondition} @emph{evclass1}...,@emph{evclassN}
                   2221: @end example
                   2222: 
                   2223: In its inclusive form, @code{ASTART} enables asynchronous event handling for all event classes named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2224: 
                   2225: @example
                   2226:   ASTART@emph{:postcondition} (@emph{evclass1}...,@emph{evclassN})
                   2227: @end example
                   2228: 
                   2229: In its exclusive form, @code{ASTART} enables asynchronous event handling for all event classes @emph{except for} those named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2230: 
                   2231: @node ASTOP
                   2232: @section ASTOP
                   2233: @cindex ASTOP
                   2234: @cindex commands, ASTOP
                   2235: 
                   2236: Disables asynchronous event handling for one or more event classes.
                   2237: 
                   2238: @emph{Syntax}
                   2239: 
                   2240: @example
                   2241:   ASTOP@emph{:postcondition}
                   2242: @end example
                   2243: 
                   2244: In its argumentless form, @code{ASTOP} disables asynchronous event handling for all event classes, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2245: 
                   2246: @example
                   2247:   ASTOP@emph{:postcondition} @emph{evclass1}...,@emph{evclassN}
                   2248: @end example
                   2249: 
                   2250: In its inclusive form, @code{ASTOP} disables asynchronous event handling for all event classes named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2251: 
                   2252: @example
                   2253:   ASTOP@emph{:postcondition} (@emph{evclass1}...,@emph{evclassN})
                   2254: @end example
                   2255: 
                   2256: In its exclusive form, @code{ASTOP} disables asynchronous event handling for all event classes @emph{except for} those named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2257: 
                   2258: @node AUNBLOCK
                   2259: @section AUNBLOCK
                   2260: @cindex AUNBLOCK
                   2261: @cindex commands, AUNBLOCK
                   2262: 
                   2263: Decrements the event block counter for one or more event classes.
                   2264: 
                   2265: @emph{Syntax}
                   2266: 
                   2267: @example
                   2268:   AUNBLOCK@emph{:postcondition}
                   2269: @end example
                   2270: 
                   2271: In its argumentless form, @code{AUNBLOCK} decrements the block counter for @emph{all} event classes, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2272: 
                   2273: @example
                   2274:   AUNBLOCK@emph{:postcondition} @emph{evclass1}...,@emph{evclassN}
                   2275: @end example
                   2276: 
                   2277: In its inclusive form, @code{AUNBLOCK} decrements the block counters for all event classes named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2278: 
                   2279: @example
                   2280:   AUNBLOCK@emph{:postcondition} (@emph{evclass1}...,@emph{evclassN}
                   2281: @end example
                   2282: 
                   2283: In its exclusive form, @code{AUNBLOCK} decrements the block counters for all event classes @emph{except for} those named in the list, provided the optional @emph{postcondition} is either @emph{true} or omitted.
                   2284: 
                   2285: 
                   2286: @node BREAK
                   2287: @section BREAK
                   2288: @cindex BREAK
                   2289: @cindex commands, BREAK
                   2290: 
                   2291: Interrupts running routine to allow interactive debugging.
                   2292: 
                   2293: @emph{Syntax}
                   2294: 
                   2295: @example
                   2296: @code{BREAK@emph{:postcondition}}
                   2297: @end example
                   2298: 
                   2299: In its argumentless form, @code{BREAK} suspends execution of running code, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   2300: 
                   2301: @example
                   2302: @code{BREAK@emph{:postcondition} @emph{breakflag}}
                   2303: @end example
                   2304: 
                   2305: @emph{FreeM Extension}
                   2306: 
1.35      snw      2307: In its single-argument form, @code{BREAK} enters the interactive debugger or sets @emph{Ctrl-C} handling and error handling characteristics, provided the optional @emph{postcondition} is @emph{true} or omitted.
1.1       snw      2308: The following table enumerates the possible values of @emph{breakflag}
                   2309: 
                   2310: @table @code
1.35      snw      2311: @item "DEBUG"
                   2312: Enters the interactive debugger
1.1       snw      2313: @item 0
                   2314: Disables @emph{Ctrl-C} handling
                   2315: @item -2
                   2316: Enables normal FreeM error handling
                   2317: @item 2
                   2318: Enables @emph{Digital Standard MUMPS} v2 error handling
                   2319: @item @emph{any integer value other than 0, 2, or -2}
                   2320: Enables @emph{Ctrl-C} handling
                   2321: @end table
                   2322: 
                   2323: @node CLOSE
                   2324: @section CLOSE
                   2325: @cindex CLOSE
                   2326: @cindex commands, CLOSE
                   2327: 
                   2328: Closes an input/output device.
                   2329: 
                   2330: @emph{Syntax}
                   2331: 
                   2332: @example
                   2333: @code{CLOSE@emph{:postcondition}}
                   2334: @end example
                   2335: 
                   2336: In its argumentless form, @code{CLOSE} closes all I/O devices except for device 0 (the @code{HOME} device), provided the optional @emph{postcondition} is @emph{true} or omitted.
                   2337: 
                   2338: @example
                   2339: @code{CLOSE@emph{:postcondition} @emph{channel}}
                   2340: @end example
                   2341: 
                   2342: In its single-argument form, @code{CLOSE} closes the I/O device associated with channel @emph{channel}, provided that @emph{channel} represents a currently-open device, and the optional @emph{postcondition} is @emph{true} or omitted.
                   2343: 
                   2344: @node CONST
                   2345: @section CONST
                   2346: @cindex CONST
                   2347: @cindex commands, CONST
                   2348: @cindex commands, non-standard
                   2349: @emph{FreeM Extension}
                   2350: 
                   2351: Defines a local @emph{constant}, or variable that cannot be altered after its initial definition, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   2352: 
                   2353: Constants must only be locals, and globals are not supported.
                   2354: 
                   2355: @emph{Syntax}
                   2356: 
                   2357: @example
                   2358: @code{CONST@emph{:postcondition} @emph{mref1}=@emph{initial-value1},...,@emph{mrefN}=@emph{initial-valueN}}
                   2359: @end example
                   2360: 
                   2361: @node DO
                   2362: @section DO
                   2363: @cindex DO
                   2364: @cindex commands, DO
                   2365: 
                   2366: In its inclusive form, transfers program control to one or more specified subroutines, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. Line levels of entryrefs specified in the argument list must be one, or error @code{M14} is raised.
                   2367: 
                   2368: @emph{Syntax}
                   2369: 
                   2370: @example
                   2371: DO[@emph{:postcondition}] @emph{entryref}[@emph{:postcondition}[,...]]
                   2372: @end example
                   2373: 
1.35      snw      2374: @cartouche
                   2375: @quotation
                   2376: @emph{Non-Standard Behavior}
                   2377: 
                   2378: FreeM allows @code{DO} @emph{entryref}s to follow the format of @code{+@emph{intexpr}}. In this case, the value of @emph{intexpr} will be interpreted as an offset from the first line of the current routine.
                   2379: @end quotation
                   2380: @end cartouche
                   2381: 
1.1       snw      2382: In its argumentless form, transfers control to the following block of code where the line level is one greater than the level at which @code{DO} was encountered, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2383: 
                   2384: @emph{Syntax}
                   2385: 
                   2386: @example
                   2387: DO[@emph{:postcondition}]
                   2388: @end example
                   2389: 
                   2390: @node ELSE
                   2391: @section ELSE
                   2392: @cindex ELSE
                   2393: @cindex commands, ELSE
                   2394: 
                   2395: Executes the remainder of the line of code on which @code{ELSE} is encountered only if @code{$TEST} evaluates to @emph{false}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2396: 
                   2397: @emph{Syntax}
                   2398: 
                   2399: @example
                   2400: ELSE[@emph{:postcondition}]
                   2401: @end example
                   2402: 
                   2403: @cartouche
                   2404: @quotation
                   2405: @emph{Non-Standard Behavior}
                   2406: 
                   2407: FreeM allows a @emph{postcondition} on @code{ELSE}. While explicitly forbidden in the @emph{standard}--and for good reason--it was decided that FreeM should allow postconditions everywhere, both for the sake of foolish consistency (the likes of which Emerson warned against), and for the benefit of entrants to a hypothetical future obfuscated M contest, and those with a Machiavellian predisposition to wicked perversions and undue cleverness.
                   2408: 
1.35      snw      2409: Using postconditions on @code{ELSE} should be strictly avoided in production code, as they have no practical use, and may contribute to technical debt, hardening of the arteries, hobgoblins, a small mind, a surfeit of logic, climate change, @emph{Daily WTF} rants, or the meltdown of global financial markets.
1.1       snw      2410: @end quotation
                   2411: @end cartouche
                   2412: 
                   2413: @node FOR
                   2414: @section FOR
                   2415: @cindex FOR
                   2416: @cindex commands, FOR
                   2417: 
                   2418: In its argumentless form, repeatedly executes the remainder of the line on which @code{FOR} was encountered until a @code{QUIT}, @code{GOTO}, or end-of-line is encountered, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2419: 
                   2420: @emph{Syntax}
                   2421: 
                   2422: @example
                   2423: FOR[@emph{:postcondition}]
                   2424: @end example
                   2425: 
                   2426: @cartouche
                   2427: @quotation
                   2428: @emph{Non-Standard Behavior}
                   2429: 
                   2430: When @code{$DIALECT} is set to @code{FREEM}, FreeM allows a @emph{postcondition} on @code{FOR}. Much like postconditions on @code{ELSE} and @code{IF}, this is explicitly forbidden in the @emph{standard}. The expression contained in the @emph{postcondition} is evaluated on each iteration of the @code{FOR} loop, and if it does not evaluate @emph{true}, the loop will be immediately exited. The effect is roughly similar to @code{WHILE} constructs present in other languages, but absent from standard M.
                   2431: 
                   2432: As with all non-standard features of FreeM, please exercise caution when using this feature, especially in code that is expected to run in other, less preternaturally-inclined M implementations.
                   2433: @end quotation
                   2434: @end cartouche
                   2435: 
                   2436: In its sentinel form, repeatedly executes the remainder of the line and sets a sentinel variable on each iteration, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2437: 
                   2438: On the first iteration of the loop, @emph{glvn} will be set to @emph{initalizer-expression}. On each subsequent iteration, @emph{glvn} will be incremented by @emph{increment-expression}, and the loop will terminate when @emph{glvn} meets or exceeds the value of @emph{max-expression}.
                   2439: 
                   2440: @emph{Syntax}
                   2441: 
                   2442: @example
                   2443: FOR[@emph{:postcondition}] @emph{glvn}=@emph{initializer-expression}:@emph{increment-expression}:@emph{max-expression}
                   2444: @end example
                   2445: 
                   2446: @emph{Example}
                   2447: 
                   2448: @example
1.22      snw      2449: DEFAULT.USER> FOR I=1:1:10 WRITE I,!
1.1       snw      2450: 
                   2451: 1
                   2452: 2
                   2453: 3
                   2454: 4
                   2455: 5
                   2456: 6
                   2457: 7
                   2458: 8
                   2459: 9
                   2460: 10
                   2461: 
1.22      snw      2462: DEFAULT.USER> FOR I=2:2:10 WRITE I,!
1.1       snw      2463: 
                   2464: 2
                   2465: 4
                   2466: 6
                   2467: 8
                   2468: 10
                   2469: @end example
                   2470: 
                   2471: In its explicit parameter form, a variable is set to each of a series of explicit values, once per iteration, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. The loop terminates when no more values are available.
                   2472: 
                   2473: @emph{Syntax}
                   2474: 
                   2475: @example
                   2476: FOR[@emph{:postcondition}] @emph{glvn}=@emph{expr1}[,..@emph{exprN}]
                   2477: @end example
                   2478: 
                   2479: @emph{Example}
                   2480: 
                   2481: @example
1.22      snw      2482: DEFAULT.USER> FOR I=60,"FOO",-3,"George",1450,$HOROLOG WRITE I,!
1.1       snw      2483: 
                   2484: 60
                   2485: FOO
                   2486: -3
                   2487: George
                   2488: 1450
                   2489: 66106,52388
                   2490: @end example
                   2491: 
                   2492: @node GOTO
                   2493: @section GOTO
                   2494: @cindex GOTO
                   2495: @cindex commands, GOTO
                   2496: 
                   2497: Transfers program execution to another line of code, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. Attempting to @code{GOTO} a different line level or a different block when the line level of @code{GOTO} is greater than one will raise error @code{M45}.
                   2498: 
                   2499: @emph{Syntax}
                   2500: 
                   2501: @example
                   2502: GOTO[@emph{:postcondition}] @emph{entryref}
                   2503: @end example
                   2504: 
1.35      snw      2505: @cartouche
                   2506: @quotation
                   2507: @emph{Non-Standard Behavior}
                   2508: 
                   2509: FreeM allows @code{GOTO} @emph{entryref}s to follow the format of @code{+@emph{intexpr}}. In this case, the value of @emph{intexpr} will be interpreted as an offset from the first line of the current routine.
                   2510: @end quotation
                   2511: @end cartouche
                   2512: 
                   2513: 
1.1       snw      2514: @node HALT
                   2515: @section HALT
                   2516: @cindex HALT
                   2517: @cindex commands, HALT
                   2518: 
                   2519: Halts program execution and frees resources allocated during execution, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2520: 
                   2521: @emph{Syntax}
                   2522: 
                   2523: @example
                   2524: HALT[@emph{:postcondition}]
                   2525: @end example
                   2526: 
                   2527: @node HANG
                   2528: @section HANG
                   2529: @cindex HANG
                   2530: @cindex commands, HANG
                   2531: 
                   2532: Temporarily suspends the program for @emph{expr} seconds, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. Values of @emph{expr} that are zero or less than zero are ignored.
                   2533: 
                   2534: @emph{Syntax}
                   2535: 
                   2536: @example
                   2537: HANG[@emph{:postcondition}] @emph{expr}
                   2538: @end example
                   2539: 
                   2540: @cartouche
                   2541: @quotation
                   2542: @emph{Non-Standard Behavior}
                   2543: 
                   2544: FreeM supports sub-second values for @emph{expr}.
                   2545: @end quotation
                   2546: @end cartouche
                   2547: 
                   2548: @node IF
                   2549: @section IF
                   2550: @cindex IF
                   2551: @cindex commands, IF
                   2552: 
                   2553: In its argumented form, allows the remainder of the line of code following @code{IF} to execute only if all @emph{tvexpr}s evaluate to @emph{true}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2554: 
                   2555: @emph{Syntax}
                   2556: @example
                   2557: IF[@emph{:postcondition}] @emph{tvexpr}[,...@emph{tvexpr}]
                   2558: @end example
                   2559: 
                   2560: In its argumentless form, allows the remainder of the line of code following @code{IF} to execute only if @code{$TEST} evaluates to @emph{1}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2561: 
                   2562: @emph{Syntax}
                   2563: @example
                   2564: IF[@emph{:postcondition}]
                   2565: @end example
                   2566: 
                   2567: @node JOB
                   2568: @section JOB
                   2569: @cindex JOB
                   2570: @cindex commands, JOB
                   2571: 
                   2572: Executes @emph{entryref} in a separate process, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2573: 
                   2574: @emph{Syntax}
                   2575: @example
                   2576: JOB[@emph{:postcondition}] @emph{entryref}[:@emph{job-parameters}[:@emph{timeout}]]
                   2577: @end example
                   2578: 
                   2579: If @emph{timeout} is supplied, FreeM will set @code{$TEST} to @emph{1} if the child process completes within @emph{timeout} seconds.
                   2580: 
                   2581: @node KILL
                   2582: @section KILL
                   2583: @cindex KILL
                   2584: @cindex commands, KILL
                   2585: 
                   2586: In its inclusive form, @code{KILL} deletes the specified @emph{glvn}s and their descendant subscripts, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2587: 
                   2588: @emph{Syntax}
                   2589: @example
                   2590: KILL[@emph{:postcondition}] @emph{glvn}[,...@emph{glvn}]
                   2591: @end example
                   2592: 
                   2593: In its exclusive form, @code{KILL} deletes all local variables @emph{except} for those specified by @emph{lvn}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2594: 
                   2595: @emph{Syntax}
                   2596: @example
                   2597: KILL[@emph{:postcondition}] (@emph{lvn}[,...@emph{lvn}])
                   2598: @end example
                   2599: 
                   2600: In its argumentless form, @code{KILL} deletes all local variables, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2601: 
                   2602: @emph{Syntax}
                   2603: @example
                   2604: KILL[@emph{:postcondition}]
                   2605: @end example
                   2606: 
                   2607: @node KSUBSCRIPTS
                   2608: @section KSUBSCRIPTS
                   2609: @cindex KSUBSCRIPTS
                   2610: @cindex commands, KSUBSCRIPTS
                   2611: 
                   2612: Kills only the descendant subscripts (but not the data value) of a referenced global, local, or SSVN (where allowed).
                   2613: 
                   2614: @emph{Syntax}
                   2615: 
                   2616: @example
                   2617: KSUBSCRIPTS@emph{:postcondition} @emph{var1},...
                   2618: @end example
                   2619: 
                   2620: In the above @emph{inclusive} form, @code{KVALUE} will kill the descendant subscripts at each local, global, or SSVN node specified in the list (provided that the optional @emph{postcondition} is @emph{true} or omitted), but will leave the data value intact.
                   2621: 
                   2622: @cartouche
                   2623: @quotation
                   2624: @emph{Note}
1.32      snw      2625: The below @emph{argumentless} and @emph{exclusive} forms of @code{KSUBSCRIPTS} are not implemented in FreeM, as of version 0.64.0-rc1, but are planned for a future release.
1.1       snw      2626: @end quotation
                   2627: @end cartouche
                   2628: 
                   2629: @example
                   2630: KSUBSCRIPTS@emph{:postcondition}
                   2631: @end example
                   2632: 
                   2633: In the above @emph{argumentless} form, @code{KSUBSCRIPTS} will kill the descendant subscripts at the root of each local variable (provided that the optional @emph{postcondition} is @emph{true} or omitted), but will leave data values intact.
                   2634: 
                   2635: @example
                   2636: KSUBSCRIPTS@emph{:postcondition} (@emph{var1},...)
                   2637: @end example
                   2638: 
                   2639: In the above @emph{exclusive} form, @code{KSUBSCRIPTS} will kill the descendant subscripts of all local variables, @emph{with the exception of} those named in the list, provided that the optional @emph{postcondition} is @emph{true} or omitted, while leaving their data values intact.
                   2640: 
                   2641: 
                   2642: @node KVALUE
                   2643: @section KVALUE
                   2644: @cindex KVALUE
                   2645: @cindex commands, KVALUE
                   2646: 
                   2647: Kills only the data value (but not descendant subscripts) of a referenced global, local, or SSVN (where allowed).
                   2648: 
                   2649: @emph{Syntax}
                   2650: 
                   2651: @example
                   2652: KVALUE@emph{:postcondition} @emph{var1},...
                   2653: @end example
                   2654: 
                   2655: In the above @emph{inclusive} form, @code{KVALUE} will kill the data values at each local, global, or SSVN node specified in the list (provided that the optional @emph{postcondition} is @emph{true} or omitted), but will leave descendant subscripts intact.
                   2656: 
                   2657: @cartouche
                   2658: @quotation
                   2659: @emph{Note}
1.32      snw      2660: The below @emph{argumentless} and @emph{exclusive} forms of @code{KVALUE} are not implemented in FreeM, as of version 0.64.0-rc1, but are planned for a future release.
1.1       snw      2661: @end quotation
                   2662: @end cartouche
                   2663: 
                   2664: @example
                   2665: KVALUE@emph{:postcondition}
                   2666: @end example
                   2667: 
                   2668: In the above @emph{argumentless} form, @code{KVALUE} will kill the data values at the root of each local variable (provided that the optional @emph{postcondition} is @emph{true} or omitted), but will leave descendant subscripts intact.
                   2669: 
                   2670: @example
                   2671: KVALUE@emph{:postcondition} (@emph{var1},...)
                   2672: @end example
                   2673: 
                   2674: In the above @emph{exclusive} form, @code{KVALUE} will kill the data values of all local variables, @emph{with the exception of} those named in the list, provided that the optional @emph{postcondition} is @emph{true} or omitted, while leaving their descendant subscripts intact.
                   2675: 
                   2676: @node LOCK
                   2677: @section LOCK
                   2678: @cindex LOCK
                   2679: @cindex commands, LOCK
                   2680: 
                   2681: Acquires or releases ownership of names.
                   2682: 
                   2683: In its argumentless form, @code{LOCK} releases ownership of all names previously locked by the current process, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2684: 
                   2685: @emph{Syntax}
                   2686: @example
                   2687: LOCK[@emph{:postcondition}]
                   2688: @end example
                   2689: 
                   2690: In its incremental form, increments or decrements the lock counter for each specified @emph{name}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. Ownership of each @emph{name} is considered to be the current process as long as the lock counter for @emph{name} is greater than zero. If @emph{timeout} is specified, FreeM will wait no more than @emph{timeout} seconds in attempting to acquire ownership of @emph{name}.
                   2691: 
                   2692: If @code{LOCK} succeeds within @emph{timeout}, @code{$TEST} is set to @emph{1}. Otherwise, @code{$TEST} is set to @emph{0}.
                   2693: 
                   2694: @emph{Syntax}
                   2695: @example
                   2696: LOCK[@emph{:postcondition}] [+|-]@emph{name}[:@emph{timeout}][,...[+|-]@emph{name}[:@emph{timeout}]]
                   2697: @end example
                   2698: 
                   2699: @emph{Example}
                   2700: 
1.26      snw      2701: This example will increment the lock counter for @code{^SNW} and decrement the lock counter for @code{^MJR}.
1.1       snw      2702: 
                   2703: @example
1.26      snw      2704: LOCK +^SNW,-^MJR
1.1       snw      2705: @end example
                   2706: 
                   2707: In its non-incremental form, @code{LOCK} releases all @code{LOCK}s held by the current process, and then attempts to acquire a lock on each @emph{name}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. If @emph{timeout} is supplied, FreeM will attempt to lock @emph{name} for no more than @emph{timeout} seconds.
                   2708: 
                   2709: If @code{LOCK} succeeds within @emph{timeout}, @code{$TEST} is set to @emph{1}. Otherwise, @code{$TEST} is set to @emph{0}.
                   2710: 
                   2711: @emph{Syntax}
                   2712: @example
                   2713: LOCK[@emph{:postcondition}] @emph{name}[:@emph{timeout}][,...@emph{name}[:@emph{timeout}]]
                   2714: @end example
                   2715: 
                   2716: @node MAP
                   2717: @section MAP
                   2718: @cindex MAP
                   2719: @cindex commands, MAP
                   2720: @cindex commands, implementation-specific
                   2721: @cindex commands, non-standard
                   2722: 
                   2723: Maps global name @code{gvn} to be mapped to the non-default namespace @emph{expr V namespace}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2724: 
                   2725: @emph{Syntax}
                   2726: 
                   2727: @example
                   2728: MAP[@emph{:postcondition}] GLOBAL @emph{gvn}=@emph{expr V namespace}
                   2729: @end example
                   2730: 
                   2731: @node MERGE
                   2732: @section MERGE
                   2733: @cindex MERGE
                   2734: @cindex commands, MERGE
                   2735: 
                   2736: Merges the contents of one global, local, or SSVN subtree to another global, local, or SSVN.
                   2737: 
                   2738: @emph{Syntax}
                   2739: 
                   2740: @example
                   2741: @code{MERGE A=^$JOB}
                   2742: @end example
                   2743: 
                   2744: The above example will merge the @code{^$JOB} SSVN into the @code{A} local. Note that the FreeM implementation of @code{MERGE} does not yet support multiple merge arguments. Returns error @code{M19} if either the source or the target variable are descendants of each other.
                   2745: 
                   2746: @node NEW
                   2747: @section NEW
                   2748: @cindex NEW
                   2749: @cindex commands, NEW
                   2750: 
                   2751: In all forms of @code{NEW}, @emph{name} must be a local variable name or @code{NEW}-able structured or intrinsic system variable.
                   2752: 
                   2753: In its inclusive form, @code{NEW} saves each specified @emph{name} on the process stack and removes it, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.  When the current stack frame is exited, the previous values are restored.
                   2754: 
                   2755: @emph{Syntax}
                   2756: 
                   2757: @example
                   2758: NEW[@emph{:postcondition}] @emph{name}[,...@emph{name}]
                   2759: @end example
                   2760: 
                   2761: In its exclusive form, @code{NEW} saves all local variables @emph{except} those named (each @emph{name}) and removes them, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. When the current stack frame is exited, the previous values are restored.
                   2762: 
                   2763: @emph{Syntax}
                   2764: @example
                   2765: NEW[@emph{:postcondition}] (@emph{name}[,...@emph{name}])
                   2766: @end example
                   2767: 
                   2768: In its argumentless form, @code{NEW} saves all local variables and removes them, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. When the current stack frame is exited, the previous values are restored.
                   2769: 
                   2770: @emph{Syntax}
                   2771: @example
                   2772: NEW@emph{:postcondition} @emph{name}=@emph{expr}
                   2773: @end example
                   2774: 
                   2775: In its initializing form, @code{NEW} stacks variable @emph{name} and sets its value to @emph{expr}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. When the current stack frame is exited, the previous value is restored.
                   2776: 
1.26      snw      2777: @emph{Syntax}
                   2778: @example
                   2779: NEW@emph{:postcondition} @emph{name}=$%@emph{^CLASS}(@emph{initializer-list})
                   2780: @end example
                   2781: 
                   2782: In its object-oriented form, @code{NEW} creates an instance of class @emph{^CLASS} in local variable @emph{name} and calls the constructor of @emph{^CLASS}, passing @emph{initializer-list} as its argument(s).
                   2783: 
1.1       snw      2784: @node OPEN
                   2785: @section OPEN
                   2786: @cindex OPEN
                   2787: @cindex commands, OPEN
                   2788: 
                   2789: Opens sequential or socket I/O devices and files and associates them with a numeric FreeM input/output channel.
                   2790: 
                   2791: @emph{Syntax (Sequential Files)}
                   2792: 
                   2793: @example
                   2794: @code{OPEN@emph{:postcondition} @emph{channel}:"@emph{filename}/@emph{access-mode}"}
                   2795: @end example
                   2796: 
                   2797: Opens @emph{filename} for reading and/or writing, and associates the file with FreeM I/O channel @emph{channel}, provided that the optional @emph{postcondition} is @emph{true} or omitted.
                   2798: The below table lists the valid options for @emph{access-mode}:
                   2799: 
                   2800: @table @code
                   2801: @item r
                   2802: Read-only access
                   2803: @item w
                   2804: Create a new file for write access
                   2805: @item a
                   2806: Write access; append to existing file
                   2807: @item r+
                   2808: Read/write access
                   2809: @end table
                   2810: 
                   2811: @cartouche
                   2812: @quotation
                   2813: @emph{I/O Path}
                   2814: 
                   2815: You cannot specify a fully-qualified filesystem path in the FreeM @code{OPEN} command. By default, FreeM will assume that @emph{filename} exists in the directory indicated in @code{^$JOB($JOB,"CWD")}. If you wish to
                   2816: access files in other directories, you must first set the @emph{I/O Path} in @code{^$JOB($JOB,"IOPATH")}.
                   2817: 
                   2818: The following example will set the I/O path to @code{/etc}:
                   2819: 
                   2820: @example
                   2821: @code{SET ^$JOB($JOB,"IOPATH")="/etc"}
                   2822: @end example
                   2823: 
                   2824: @end quotation
                   2825: @end cartouche
                   2826: 
                   2827: If @emph{channel} was already @code{OPEN}ed in the current process, calling @code{OPEN} on the same channel again implicitly closes the file or device currently associated with @emph{channel}.
                   2828: 
                   2829: @emph{Syntax (Network Sockets)}
                   2830: 
                   2831: Network sockets use a dedicated range of FreeM I/O channels ranging from 100-255. @code{OPEN}ing a socket I/O channel does @emph{not} implicitly connect the socket. Connecting the socket to the specified remote host is accomplished by the @code{/CONNECT} control mnemonic supplied to the @code{USE} command.
                   2832: 
                   2833: @example
                   2834:   OPEN@emph{:postcondition} @emph{socket-channel}:"@emph{hostname-or-address}:@emph{port}:@emph{address-family}:@emph{connection-type}"
                   2835: @end example
                   2836: 
                   2837: @emph{Socket Parameters}
                   2838: 
                   2839: @table @emph
                   2840: 
                   2841: @item socket-channel
                   2842: The socket I/O channel to use. This must be in the range of 100-255.
                   2843: 
                   2844: @item hostname-or-address
                   2845: The hostname or IP address to connect to. If a hostname is supplied, @code{OPEN} will implictly do a name lookup, the mechanism of which is typically determined by the configuration of @code{/etc/nsswitch.conf} on most UNIX and UNIX-like platforms.
                   2846: 
                   2847: @item port
                   2848: The TCP or UDP port to which the socket will connect on the remote host.
                   2849: 
                   2850: @item address-family
                   2851: The address family to use. Either @emph{IPV4} or @emph{IPV6}.
                   2852: 
                   2853: @item connection-type
                   2854: Which connection type to use. Either @emph{TCP} or @emph{UDP}.
                   2855: 
                   2856: @end table
                   2857: 
                   2858: If you do not specify the address family and connection type, they will default to @emph{IPV4} and @emph{TCP}, respectively.
                   2859: 
                   2860: @node QUIT
                   2861: @section QUIT
                   2862: @cindex QUIT
                   2863: @cindex commands, QUIT
                   2864: 
                   2865: @code{QUIT} will end execution of the current process level, optionally returning @emph{expr}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2866: 
                   2867: @code{QUIT} with @emph{expr} when an argument is not expected will raise error @code{M16}; @code{QUIT} without @emph{expr} when an argument is expected will raise error @code{M17}.
                   2868: 
                   2869: Argumentless @code{QUIT} may also be used to exit a @code{FOR} loop occurring on the same line.
                   2870: 
                   2871: @emph{Syntax}
                   2872: @example
                   2873: QUIT[@emph{:postcondition}] [@emph{expr}]
                   2874: @end example
                   2875: 
                   2876: @node READ
                   2877: @section READ
                   2878: @cindex READ
                   2879: @cindex commands, READ
                   2880: 
                   2881: The @code{READ} command takes input from I/O channel @code{$IO} and stores it into specified variables, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2882: 
                   2883: @emph{Syntax}
                   2884: @example
                   2885: READ[@emph{:postcondition}] @emph{read-argument}[,...@emph{read-argument}]
                   2886: @end example
                   2887: 
                   2888: Each @emph{read-argument} may be one of the following:
                   2889: 
                   2890: @table @asis
                   2891: 
                   2892: @item String Literal
                   2893: String literal @emph{read-argument}s will be output to @code{$IO} unmodified.
                   2894: 
                   2895: @item Format Specifier
                   2896: One or more of the following:
                   2897: 
                   2898: @table @asis
                   2899: @item @code{!} (newline)
                   2900: Advances the cursor down by one line and returns it to the first column.
                   2901: 
                   2902: @item @code{#} (form-feed)
                   2903: Advances the screen down by @code{$ZROWS} and moves the cursor to the upper-left corner of the screen.
                   2904: 
                   2905: @item @code{?@emph{n}} (position)
                   2906: Advances the cursor and @code{$X} forward to position @emph{n}.
                   2907: 
                   2908: @end table
                   2909: 
                   2910: @item Single-Character Read (@code{*@emph{variable-name}[@emph{:timeout}]})
                   2911: Reads one character into variable @emph{variable-name}. If the optional @emph{timeout} is specified, will wait @emph{timeout} seconds to retrieve one character. If a character is read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{1}. If no character is read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{0}.
                   2912: 
                   2913: @item Variable-Length Character Read (@code{@emph{variable-name}[@emph{:timeout}]})
                   2914: Reads characters into @emph{variable-name} until the character or character pair in @code{^$DEVICE(@emph{io-channel},"OPTIONS","TERMINATOR")} is encountered. If the optional @emph{timeout} is specified, will wait @emph{timeout} seconds to retrieve characters. If characters are read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{1}. If no character is read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{0}.
                   2915: 
                   2916: @item Fixed-Length Character Read (@code{@emph{variable-name}#@emph{count}[@emph{:timeout}]})
                   2917: Reads @emph{count} characters into @emph{variable-name}. If the optional @emph{timeout} is specified, will wait @emph{timeout} seconds to retrieve characters. If characters are read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{1}. If no character is read within @emph{timeout} seconds, @code{$TEST} will be set to @emph{0}.
                   2918: 
                   2919: @item Control Mnemonic (@code{/@emph{control-mnemonic}[@emph{(arg1[,...argN])}]})
                   2920: Outputs X3.64 control mnemonic @emph{control-mnemonic} to @code{$IO}. Please see the appendix on X3.64 Control Mnemonics for more information.
                   2921: 
                   2922: @end table
                   2923: 
                   2924: @node SET
                   2925: @section SET
                   2926: @cindex SET
                   2927: @cindex commands, SET
                   2928: 
                   2929: The @code{SET} command places values into one or more variables, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2930: 
                   2931: @emph{Syntax}
                   2932: @example
                   2933: SET[@emph{:postcondition}] @emph{set-argument}[=@emph{expression} | @emph{postfix-operator}][@emph{,...set-argument}[=@emph{expression} | @emph{postfix-operator}]]
                   2934: @end example
                   2935: 
                   2936: Each @emph{set-argument} can be:
                   2937: 
                   2938: @table @asis
                   2939: @item @emph{variable-name}
                   2940: A local variable, global variable, writable intrinsic special variable, or writable structured system variable.
                   2941: 
                   2942: @item @emph{lhs-function}
                   2943: @code{$EXTRACT} or @code{$PIECE}.
                   2944: @end table
                   2945: 
                   2946: If any grouping of @emph{set-argument}s is surrounded by parentheses, all @emph{set-argument}s in the parenthesized group will be set to the result of @emph{expression}.
                   2947: 
                   2948: If @emph{postfix-operator} is used instead of @code{=@emph{expression}}, the results of applying @emph{postfix-operator} to the @emph{set-argument} will be stored in @emph{set-argument}. @emph{postfix-operator} may not be used following a parenthesized group of @emph{set-argument}s.
                   2949: 
                   2950: @emph{Example (postfix-operator)}
                   2951: 
                   2952: @example
                   2953: SET A++,B-- ; increments A, decrements B
                   2954: @end example
                   2955: 
                   2956: @node TCOMMIT
                   2957: @section TCOMMIT
                   2958: @cindex TCOMMIT
                   2959: @cindex commands, TCOMMIT
                   2960: 
                   2961: Commits all pending transactions to the data files, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   2962: 
                   2963: @emph{Syntax}
                   2964: @example
                   2965: TCOMMIT[@emph{:postcondition}]
                   2966: @end example
                   2967: 
                   2968: @node THEN
                   2969: @section THEN
                   2970: @cindex THEN
                   2971: @cindex commands, THEN
                   2972: 
                   2973: Saves the value of @code{$TEST} until the end of the current line, restoring it at the end of the current line or when a @code{QUIT} is encountered. @code{THEN} should be used in all new code in conjunction with @code{IF}.
                   2974: 
                   2975: @emph{Example}
                   2976: @example
                   2977: IF 1 THEN  WRITE "HELLO!",!
                   2978: @end example
                   2979: 
                   2980: @node THROW
                   2981: @section THROW
                   2982: @cindex THROW
                   2983: @cindex commands, THROW
                   2984: @cindex commands, non-standard
                   2985: @emph{FreeM Extension}
                   2986: 
                   2987: Raises an error condition as long as the optional @emph{postcondition} is @emph{true} or omitted.
                   2988: 
                   2989: @emph{Syntax}
                   2990: 
                   2991: @example
                   2992: @code{THROW@emph{:postcondition} @emph{expr V error-code}}
                   2993: @end example
                   2994: 
                   2995: @emph{Example}
                   2996: 
                   2997: @example
                   2998: @code{THROW "M102"}
                   2999: @end example
                   3000: 
                   3001: @node TROLLBACK
                   3002: @section TROLLBACK
                   3003: @cindex TROLLBACK
                   3004: @cindex commands, TROLLBACK
                   3005: 
                   3006: Rolls back all pending transactions for the current process, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   3007: 
                   3008: @emph{Syntax}
                   3009: 
                   3010: @example
                   3011: TROLLBACK[@emph{:postcondition}]
                   3012: @end example
                   3013: 
                   3014: @node TSTART
                   3015: @section TSTART
                   3016: @cindex TSTART
                   3017: @cindex commands, TSTART
                   3018: 
                   3019: Introduces a new transaction level, incrementing @code{$TLEVEL}, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted. Any global data file operations encountered when @code{$TLEVEL} is greater than zero will not be committed to the global data files until @code{TCOMMIT} is encountered.
                   3020: 
                   3021: If a transaction is restartable, variables in the @emph{variables-list} will be restored to their original values on a restart of the transaction.
                   3022: 
                   3023: @emph{Syntax}
                   3024: 
                   3025: @example
                   3026: TSTART[@emph{:postcondition}] @emph{<variables-list>}:@emph{<transaction-parameters>}
                   3027: @end example
                   3028: 
                   3029: @emph{<variables-list>} can be:
                   3030: 
                   3031: @table @asis
                   3032: 
                   3033: @item @code{()}
                   3034: Do not save off any local variables. Makes the transaction non-restartable.
                   3035: 
                   3036: @item @code{*}
                   3037: Save off all local variables. Makes the transaction restartable.
                   3038: 
                   3039: @item @code{@emph{variableName}}
                   3040: Saves off only one local variable, @emph{variableName}. Makes the transaction restartable.
                   3041: 
                   3042: @item @code{(@emph{variableName1},...,@emph{variableNameN})}
                   3043: Saves off all local variables listed. Makes the transaction restartable.
                   3044: 
                   3045: @end table
                   3046: 
                   3047: @emph{<transaction-parameters>} can be:
                   3048: 
                   3049: @table @asis
                   3050: 
                   3051: @item @code{S[ERIAL]}
                   3052: Forces ACID properties on the transaction. When @code{SERIAL} is not selected, transactions occur in batch mode, and no attempt is made to guarantee ACID properties.
                   3053: 
                   3054: @item @code{T[RANSACTIONID]=@emph{transaction-id}}
                   3055: Sets the ID of the transaction to @emph{transaction-id}
                   3056: 
                   3057: @end table
                   3058: 
                   3059: If you are using more than one transaction parameter, surround all of them in parentheses and separate them with commas, e.g.:
                   3060: 
                   3061: @example
                   3062: TSTART (FOO,BAR):(SERIAL,TRANSACTIONID="FOO")
                   3063: @end example
                   3064: 
                   3065: @node UNMAP
                   3066: @section UNMAP
                   3067: @cindex UNMAP
                   3068: @cindex commands, UNMAP
                   3069: @cindex commands, implementation-specific
                   3070: @cindex commands, non-standard
                   3071: 
                   3072: Removes any mapping connecting @emph{gvn} to a non-default namespace, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   3073: 
                   3074: @emph{Syntax}
                   3075: 
                   3076: @example
                   3077: UNMAP GLOBAL @emph{gvn}
                   3078: @end example
                   3079: 
                   3080: @node USE
                   3081: @section USE
                   3082: @cindex USE
                   3083: @cindex commands, USE
                   3084: 
                   3085: Sets @code{$IO} to a particular FreeM I/O channel, allowing @code{READ}s from and @code{WRITE}s to the associated terminal, sequential file, or network socket. Also sets various device parameters.
                   3086: 
                   3087: @emph{Syntax (Terminal)}
                   3088: 
                   3089: @example
                   3090:   USE@emph{:postcondition} @emph{io-channel}[:(@emph{right-margin}:@emph{input-field-length}:@emph{device-status-word}:@emph{position}:@emph{line-terminator}:@emph{break-key})]
                   3091: @end example
                   3092: 
                   3093: For terminals, @emph{io-channel} must be 0.
                   3094: 
                   3095: Semantic and functional description of each device parameter TBA.
                   3096: 
                   3097: @emph{Syntax (Sequential Files)}
                   3098: 
                   3099: @example
                   3100:   USE@emph{:postcondition} @emph{io-channel}[:@emph{seek-position}:@emph{terminator}:@emph{nodelay})]
                   3101: @end example
                   3102: 
                   3103: For sequential files, @emph{io-channel} must be in the range 1-99.
                   3104: 
                   3105: Semantic and functional description of each device parameter TBA.
                   3106: 
                   3107: @emph{Syntax (Network Sockets)}
                   3108: 
                   3109: @example
                   3110:   USE@emph{:postcondition} @emph{io-channel}
                   3111: @end example
                   3112: 
                   3113: The above syntax will set @code{$IO} to @emph{io-channel}, directing successive @code{READ}s and @code{WRITE}s to @emph{io-channel}, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3114: 
                   3115: @example
                   3116:   USE@emph{:postcondition} @emph{io-channel}:/CONNECT
                   3117: @end example
                   3118: 
                   3119: The above syntax will set @code{$IO} to @emph{io-channel}, as in the prior example, but will also attempt to connect to the host and port specified for @emph{io-channel} when it was @code{OPEN}ed. The @code{/CONNECT} control mnemonic is only valid for socket channels whose connection type is @code{TCP}. Using @code{/CONNECT} on a @code{UDP} socket channel will throw @code{SCKAERR} (error code 55).
                   3120: 
                   3121: For network sockets, @emph{io-channel} must be in the range 100-255.
                   3122: 
                   3123: @node VIEW
                   3124: @section VIEW
                   3125: @cindex VIEW
                   3126: @cindex commands, VIEW
                   3127: 
                   3128: Provides write access to various FreeM internal parameters, provided the optional @emph{postcondition} evaluates to @emph{true} or is omitted.
                   3129: 
                   3130: @emph{Syntax}
                   3131: @example
                   3132: VIEW[@emph{:postcondition}] @emph{view-number}[:@emph{view-argument}[:@emph{view-argument}...]]
                   3133: @end example
                   3134: 
                   3135: The @emph{view-number} argument can be one of the following:
                   3136: 
                   3137: @table @asis
                   3138: 
                   3139: @item @code{21} - Close All Globals
                   3140: Closes all global data files open in the current process. Takes no arguments.
                   3141: 
                   3142: @emph{Syntax}
                   3143: @example
                   3144: VIEW 21
                   3145: @end example
                   3146: 
                   3147: @item @code{52} - Set G0 Input Translation Table for @code{$IO}
                   3148: 
                   3149: @emph{Syntax}
                   3150: @example
                   3151: VIEW 52:@emph{expr V trantab}
                   3152: @end example
                   3153: 
                   3154: @item @code{53} - Set G0 Output Translation Table for @code{$IO}
                   3155: 
                   3156: @emph{Syntax}
                   3157: @example
                   3158: VIEW 53:@emph{expr V trantab}
                   3159: @end example
                   3160: 
                   3161: @item @code{54} - Set G1 Input Translation Table for @code{$IO}
                   3162: 
                   3163: @emph{Syntax}
                   3164: @example
                   3165: VIEW 54:@emph{expr V trantab}
                   3166: @end example
                   3167: 
                   3168: @item @code{55} - Set G1 Output Translation Table for @code{$IO}
                   3169: 
                   3170: @emph{Syntax}
                   3171: @example
                   3172: VIEW 55:@emph{expr V trantab}
                   3173: @end example
                   3174: 
                   3175: @item @code{62} - Set @code{$RANDOM} Seed Number
                   3176: Sets the seed number used by @code{$RANDOM} to @emph{numexpr}.
                   3177: 
                   3178: @emph{Syntax}
                   3179: @example
                   3180: VIEW 62:@emph{numexpr}
                   3181: @end example
                   3182: 
                   3183: @item @code{63} - Set @code{$RANDOM} Parameter A
                   3184: Sets the number used for @code{$RANDOM} Parameter A to @emph{numexpr}.
                   3185: 
                   3186: @emph{Syntax}
                   3187: @example
                   3188: VIEW 63:@emph{numexpr}
                   3189: @end example
                   3190: 
                   3191: @item @code{64} - Set @code{$RANDOM} Parameter B
                   3192: Sets the number used for @code{$RANDOM} Parameter B to @emph{numexpr}.
                   3193: 
                   3194: @emph{Syntax}
                   3195: @example
                   3196: VIEW 64:@emph{numexpr}
                   3197: @end example
                   3198: 
                   3199: @item @code{65} - Set @code{$RANDOM} Parameter C
                   3200: Sets the number used for @code{$RANDOM} Parameter C to @emph{numexpr}.
                   3201: 
                   3202: @emph{Syntax}
                   3203: @example
                   3204: VIEW 65:@emph{numexpr}
                   3205: @end example
                   3206: 
                   3207: @item @code{66} - Set or Clear @code{SIGTERM} Handling Flag
                   3208: Enables or disables handling of @code{SIGTERM} UNIX signals. If @emph{tvexpr} evaluates to 1 (@emph{true}), @code{SIGTERM} handling will be enabled. Otherwise, @code{SIGTERM} handling will be disabled.
                   3209: 
                   3210: @emph{Syntax}
                   3211: @example
                   3212: VIEW 66:@emph{tvexpr}
                   3213: @end example
                   3214: 
                   3215: @item @code{67} - Set or Clear @code{SIGHUP} Handling Flag
                   3216: Enables or disables handling of @code{SIGHUP} UNIX signals. If @emph{tvexpr} evaluates to 1 (@emph{true}), @code{SIGHUP} handling will be enabled. Otherwise, @code{SIGHUP} handling will be disabled.
                   3217: 
                   3218: @emph{Syntax}
                   3219: @example
                   3220: VIEW 67:@emph{tvexpr}
                   3221: @end example
                   3222: 
                   3223: @item @code{70} - Set @code{$ZSORT}/@code{$ZSYNTAX} Flag
                   3224: Selects whether @code{$ZS} resolves to @code{$ZSORT} or @code{$ZSYNTAX}.
                   3225: 
                   3226: If @emph{tvexpr} evaluates to @emph{true}, selects @code{$ZSYNTAX}. Otherwise, selects @code{$ZSORT}.
                   3227: 
                   3228: @emph{Syntax}
                   3229: @example
                   3230: VIEW 70:@emph{tvexpr}
                   3231: @end example
                   3232: 
                   3233: @item @code{71} - Set @code{$ZNEXT}/@code{$ZNAME} Flag
                   3234: Selects whether @code{$ZN} resolves to @code{$ZNEXT} or @code{$ZNAME}.
                   3235: 
                   3236: If @emph{tvexpr} evaluates to @emph{true}, selects @code{$ZNAME}. Otherwise, selects @code{$ZNEXT}.
                   3237: 
                   3238: @emph{Syntax}
                   3239: @example
                   3240: VIEW 71:@emph{tvexpr}
                   3241: @end example
                   3242: 
                   3243: @item @code{72} - Set @code{$ZPREVIOUS}/@code{$ZPIECE} Flag
                   3244: Selects whether @code{$ZP} resolves to @code{$ZPREVIOUS} or @code{$ZPIECE}.
                   3245: 
                   3246: If @emph{tvexpr} evaluates to @emph{true}, selects @code{$ZPIECE}. Otherwise, selects @code{$ZPREVIOUS}.
                   3247: 
                   3248: @emph{Syntax}
                   3249: @example
                   3250: VIEW 72:@emph{tvexpr}
                   3251: @end example
                   3252: 
                   3253: @item @code{73} - Set @code{$ZDATA}/@code{$ZDATE} Flag
                   3254: Selects whether @code{$ZD} resolves to @code{$ZDATA} or @code{$ZDATE}.
                   3255: 
                   3256: If @emph{tvexpr} evaluates to @emph{true}, selects @code{$ZDATE}. Otherwise, selects @code{$ZDATA}.
                   3257: 
                   3258: @emph{Syntax}
                   3259: @example
                   3260: VIEW 73:@emph{tvexpr}
                   3261: @end example
                   3262: 
                   3263: @item @code{79} - Set Old @code{ZJOB} vs. New @code{ZJOB} Flag
                   3264: If @emph{tvexpr} evaluates to @emph{true}, sets the @code{ZJOB} mode to new, otherwise, sets it to old.
                   3265: 
                   3266: @emph{Syntax}
                   3267: @example
                   3268: VIEW 79:@emph{tvexpr}
                   3269: @end example
                   3270: 
                   3271: @item @code{80} - Set or Clear 8-Bit Flag
                   3272: If @emph{tvexpr} evaluates to @emph{true}, sets FreeM to 8-bit mode. Otherwise, sets FreeM to 7-bit mode.
                   3273: 
                   3274: @emph{Syntax}
                   3275: @example
                   3276: VIEW 80:@emph{tvexpr}
                   3277: @end example
                   3278: 
                   3279: @item @code{81} - Set or Clear PF1 Flag
                   3280: If @emph{tvexpr} evaluates to @emph{true}, sets the @code{PF1} flag. We do not yet know what this does.
                   3281: 
                   3282: @emph{Syntax}
                   3283: @example
                   3284: VIEW 81:@emph{tvexpr}
                   3285: @end example
                   3286: 
                   3287: @item @code{83} - Set or Clear Text in @code{$ZERROR} Flag
                   3288: If @emph{tvexpr} evaluates to @emph{true}, descriptive error messages will be included in @code{$ZERROR}. Otherwise, only the short error code (i.e. @emph{ZILLFUN}) will be included in @code{$ZERROR}.
                   3289: 
                   3290: @emph{Syntax}
                   3291: @example
                   3292: VIEW 83:@emph{tvexpr}
                   3293: @end example
                   3294: 
                   3295: @item @code{92} - Set Type Mismatch Error Flag on @code{EUR2DEM}
                   3296: If @emph{tvexpr} evaluates to @emph{true}, a type mismatch error will be thrown in @code{EUR2DEM} currency conversions in certain situations that we do not yet understand.
                   3297: 
                   3298: @emph{Syntax}
                   3299: @example
                   3300: VIEW 92:@emph{tvexpr}
                   3301: @end example
                   3302: 
                   3303: @item @code{93} - Define @code{ZKEY} Production Rule
                   3304: We do not know what this does.
                   3305: 
                   3306: @item @code{96} - Set Global Prefix
                   3307: Forces global data filenames to be prefixed with the result of @emph{expr}.
                   3308: 
                   3309: @emph{Syntax}
                   3310: @example
                   3311: VIEW 96:@emph{expr V string}
                   3312: @end example
                   3313: 
                   3314: @item @code{97} - Set Global Postfix
                   3315: Forces global data filenames to be postfixed with the result of @emph{expr}.
                   3316: 
                   3317: @emph{Syntax}
                   3318: @example
                   3319: VIEW 97:@emph{expr V string}
                   3320: @end example
                   3321: 
                   3322: @item @code{98} - Set Routine Extension
                   3323: Sets the default extension for M routine filenames to the result of @emph{expr}.
                   3324: 
                   3325: @emph{Syntax}
                   3326: @example
                   3327: VIEW 98:@emph{expr V string}
                   3328: @end example
                   3329: 
                   3330: @item @code{101} - Set @code{ierr}
                   3331: Sets the FreeM internal @code{ierr} value to @emph{intexpr}. Used by some FreeM polyfills (commands or functions implemented in M code).
                   3332: 
                   3333: @emph{Syntax}
                   3334: @example
                   3335: VIEW 101:@emph{intexpr}
                   3336: @end example
                   3337: 
                   3338: @item @code{102} - Set @code{ierr} (Deferred)
                   3339: Sets the FreeM internal @code{ierr} value to @emph{intexpr}, but only after the current process stack level is exited. Used by FreeM polyfills to throw an error that will appear to come from the user's own code rather than the polyfill implementation M code.
                   3340: 
                   3341: @emph{Syntax}
                   3342: @example
                   3343: VIEW 102:@emph{intexpr}
                   3344: @end example
                   3345: 
                   3346: @item @code{103} - Signal @code{MERGE} to @code{^$WINDOW} Complete
                   3347: Signals FreeM's MWAPI implementation that a @code{MERGE} to @code{^$WINDOW} or descendant subscripts thereof has completed.
                   3348: 
                   3349: @emph{Syntax}
                   3350: @example
                   3351: VIEW 103[@emph{:subscript}]
                   3352: @end example
                   3353: 
                   3354: @item @code{110} - Set Local @code{$ORDER}/@code{$QUERY} Data Value
                   3355: Sets the local variable @code{$ORDER}/@code{$QUERY} data value to the result of @emph{expr}. We're not entirely sure what this is.
                   3356: 
                   3357: @emph{Syntax}
                   3358: @example
                   3359: VIEW 110:@emph{expr}
                   3360: @end example
                   3361: 
                   3362: @item @code{111} - Set Global @code{$ORDER}/@code{$QUERY} Data Value
                   3363: Sets the global variable @code{$ORDER}/@code{$QUERY} data value to the result of @emph{expr}. We're not entirely sure what this is.
                   3364: 
                   3365: @emph{Syntax}
                   3366: @example
                   3367: VIEW 111:@emph{expr}
                   3368: @end example
                   3369: 
                   3370: @item @code{113} - Set @code{termio} Information
                   3371: We don't know what this does.
                   3372: 
                   3373: @item @code{133} - Remember @code{ZLOAD} Directory on @code{ZSAVE}
                   3374: We don't know what this does, but it takes a @emph{tvexpr}.
                   3375: 
                   3376: @emph{Syntax}
                   3377: @example
                   3378: VIEW 133:@emph{tvexpr}
                   3379: @end example
                   3380: 
                   3381: @end table
                   3382: 
                   3383: @node WATCH
                   3384: @section WATCH
                   3385: @cindex WATCH
                   3386: @cindex commands, WATCH
                   3387: @cindex commands, debugging
                   3388: @cindex commands, implementation-specific
                   3389: @cindex commands, non-standard
                   3390: @emph{FreeM Extension}
                   3391: 
                   3392: Sets a watchpoint on a global, local, or SSVN node.
                   3393: 
                   3394: @emph{Syntax}
                   3395: 
                   3396: 
                   3397: In its @emph{argumentless} form, @code{WATCH} toggles watchpoints on and off, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3398: 
                   3399: @example
                   3400: WATCH[@emph{:postcondition}]
                   3401: @end example
                   3402: 
                   3403: In its @emph{inclusive} form, @code{WATCH} adds, removes, or examines watchpoints, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3404: 
                   3405: A @code{+} adds a new watchpoint to the following variable.
                   3406: 
                   3407: A @code{-} removes an existing watchpoint for the following variable.
                   3408: 
                   3409: A @code{?} examines the status of a watchpoint for the following variable.
                   3410: 
                   3411: @example
                   3412: WATCH[@emph{:postcondition}] [+|-|?]@emph{var1}...,[+|-|?]@emph{varN}
                   3413: @end example
                   3414: 
                   3415: 
1.28      snw      3416: The following example demonstrates turning watchpoint processing on and adding a watchpoint for global variable @code{^snw(1)}. It then changes the value of @code{^snw(1)}.
1.1       snw      3417: 
                   3418: @example
1.22      snw      3419: DEFAULT.USER> WATCH
1.1       snw      3420:  
                   3421: Watchpoints enabled.
                   3422:  
1.28      snw      3423: DEFAULT.USER> WATCH +^SNW(1)
1.1       snw      3424:  
1.28      snw      3425: Added '^SNW("1")' to the watchlist.
1.1       snw      3426:  
1.28      snw      3427: DEFAULT.USER> SET ^SNW(1)="new value"
1.1       snw      3428:  
1.28      snw      3429: >> WATCHPOINT:  ^SNW("1") => 'new value' (changed 1 times)
1.1       snw      3430: 
                   3431: @end example
                   3432: 
                   3433: The following example will remove that watchpoint:
                   3434: 
                   3435: @example
1.28      snw      3436: DEFAULT.USER> WATCH -^SNW(1)
1.1       snw      3437:  
1.28      snw      3438: Removed '^SNW("1")' from the watchlist.
1.1       snw      3439:  
1.28      snw      3440: DEFAULT.USER> WATCH ?^SNW(1)
1.1       snw      3441:  
1.28      snw      3442: '^SNW("1")' is not being watched.
1.1       snw      3443: @end example
                   3444: 
                   3445: @node WITH
                   3446: @section WITH
                   3447: @cindex WITH
                   3448: @cindex commands, WITH
                   3449: @cindex commands, non-standard
                   3450: @emph{FreeM Extension}
                   3451: 
1.26      snw      3452: NOTE: This command may be deprecated and removed in future FreeM releases.
                   3453: 
1.1       snw      3454: Sets a prefix to be applied to all subsequent local variable or constant references.
                   3455: 
                   3456: @emph{Syntax}
                   3457: 
                   3458: @example
                   3459: @code{WITH@emph{:postcondition} @emph{var-prefix}}
                   3460: @end example
                   3461: 
                   3462: In the above single-argument form, sets the @code{$WITH} prefix to @emph{var-prefix}, provided that the optional @emph{postcondition} is either @emph{true} or omitted.
                   3463: 
                   3464: The @emph{var-prefix} argument may be a string literal or any valid FreeM expression.
                   3465: 
                   3466: @example
                   3467: @code{WITH@emph{:postcondition}}
                   3468: @end example
                   3469: 
                   3470: In the above argumentless form, clears the @code{$WITH} prefix, provided the optional @emph{postcondition} is either @emph{true} or omitted. Equivalent to @code{WITH ""}.
                   3471: 
                   3472: 
                   3473: @node WRITE
                   3474: @section WRITE
                   3475: @cindex WRITE
                   3476: @cindex commands, WRITE
                   3477: 
                   3478: @node XECUTE
                   3479: @section XECUTE
                   3480: @cindex XECUTE
                   3481: @cindex commands, XECUTE
                   3482: 
                   3483: @node ZBREAK
                   3484: @section ZBREAK
                   3485: @cindex ZBREAK
                   3486: @cindex commands, ZBREAK
                   3487: @cindex commands, debugging
                   3488: @cindex commands, implementation-specific
                   3489: @cindex commands, non-standard
                   3490: @emph{FreeM Extension}
                   3491: 
                   3492: @node ZGO
                   3493: @section ZGO
                   3494: @cindex ZGO
                   3495: @cindex commands, ZGO
                   3496: @cindex commands, implementation-specific
                   3497: @cindex commands, non-standard
                   3498: @emph{FreeM Extension}
                   3499: 
                   3500: @node ZHALT
                   3501: @section ZHALT
                   3502: @cindex ZHALT
                   3503: @cindex commands, ZHALT
                   3504: @cindex commands, implementation-specific
                   3505: @cindex commands, non-standard
                   3506: @emph{FreeM Extension}
                   3507: 
                   3508: @node ZINSERT
                   3509: @section ZINSERT
                   3510: @cindex ZINSERT
                   3511: @cindex commands, ZINSERT
                   3512: @cindex commands, implementation-specific
                   3513: @cindex commands, non-standard
                   3514: @emph{FreeM Extension}
                   3515: 
                   3516: @node ZJOB
                   3517: @section ZJOB
                   3518: @cindex ZJOB
                   3519: @cindex commands, ZJOB
                   3520: @cindex commands, implementation-specific
                   3521: @cindex commands, non-standard
                   3522: @emph{FreeM Extension}
                   3523: 
                   3524: When @code{ZJOB} is used, the semantics are identical to @code{JOB}, with the exception that the @emph{timeout} is forced to be @code{0}, regardless of what the user specifies.
                   3525: 
                   3526: For more information, see @code{JOB}.
                   3527: 
                   3528: @node ZLOAD
                   3529: @section ZLOAD
                   3530: @cindex ZLOAD
                   3531: @cindex commands, ZLOAD
                   3532: @cindex commands, implementation-specific
                   3533: @cindex commands, non-standard
                   3534: @emph{FreeM Extension}
                   3535: 
                   3536: Loads routine @emph{<routine-name>} into FreeM's routine buffer, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3537: 
                   3538: @emph{Syntax}
                   3539: 
                   3540: @example
                   3541: ZLOAD@emph{:postcondition} @emph{<routine-name>}
                   3542: @end example
                   3543: 
                   3544: @node ZNEW
                   3545: @section ZNEW
                   3546: @cindex ZNEW
                   3547: @cindex commands, ZNEW
                   3548: @cindex commands, implementation-specific
                   3549: @cindex commands, non-standard
                   3550: @emph{FreeM Extension}
                   3551: 
                   3552: @node ZPRINT
                   3553: @section ZPRINT
                   3554: @cindex ZPRINT
                   3555: @cindex commands, ZPRINT
                   3556: @cindex commands, implementation-specific
                   3557: @cindex commands, non-standard
                   3558: @emph{FreeM Extension}
                   3559: 
                   3560: Prints the contents of the current routine buffer, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3561: 
                   3562: @emph{Syntax}
                   3563: 
                   3564: @example
                   3565: ZPRINT@emph{:postcondition}
                   3566: @end example
                   3567: 
                   3568: @node ZQUIT
                   3569: @section ZQUIT
                   3570: @cindex ZQUIT
                   3571: @cindex commands, ZQUIT
                   3572: @cindex commands, implementation-specific
                   3573: @cindex commands, non-standard
                   3574: @emph{FreeM Extension}
                   3575: 
                   3576: In its single-argument form, quits from @emph{levels} levels of the stack, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3577: 
                   3578: In its argumentless form, quits from @code{$STACK} levels of the stack, provided the optional @emph{postcondition} is @emph{true} or omitted.
                   3579: 
                   3580: @emph{Syntax}
                   3581: 
                   3582: @example
                   3583: @code{ZQUIT@emph{:postcondition} [@emph{levels}]}
                   3584: @end example
                   3585: 
                   3586: @node ZREMOVE
                   3587: @section ZREMOVE
                   3588: @cindex ZREMOVE
                   3589: @cindex commands, ZREMOVE
                   3590: @cindex commands, implementation-specific
                   3591: @cindex commands, non-standard
                   3592: @emph{FreeM Extension}
                   3593: 
                   3594: @node ZSAVE
                   3595: @section ZSAVE
                   3596: @cindex ZSAVE
                   3597: @cindex commands, ZSAVE
                   3598: @cindex commands, implementation-specific
                   3599: @cindex commands, non-standard
                   3600: @emph{FreeM Extension}
                   3601: 
                   3602: @node ZTRAP
                   3603: @section ZTRAP
                   3604: @cindex ZTRAP
                   3605: @cindex commands, ZTRAP
                   3606: @cindex commands, debugging
                   3607: @cindex commands, implementation-specific
                   3608: @cindex commands, non-standard
                   3609: @emph{FreeM Extension}
                   3610: 
                   3611: @node ZWRITE
                   3612: @section ZWRITE
                   3613: @cindex ZWRITE
                   3614: @cindex commands, ZWRITE
                   3615: @cindex commands, implementation-specific
                   3616: @cindex commands, non-standard
                   3617: @emph{FreeM Extension}
                   3618: 
                   3619: Writes the names and values of M variables to @code{$IO}.
                   3620: 
                   3621: @emph{Syntax}
                   3622: 
                   3623: @example
                   3624: ZWRITE@emph{:postcondition}
                   3625: @end example
                   3626: 
                   3627: In the argumentless form, writes the names and values of all local variables to @code{$IO} if the optional @emph{postcondition} is @emph{true} or omitted.
                   3628: 
                   3629: @example
                   3630: ZWRITE@emph{:postcondition} @emph{ArrayName},@dots{}
                   3631: @end example
                   3632: 
                   3633: In the inclusive form, writes the names and values of all local, global, or structured system variables specified in the list of @emph{ArrayName}s to @code{$IO} if the optional @emph{postcondition} is @emph{true} or omitted.
                   3634: 
                   3635: @example
                   3636: ZWRITE@emph{:postcondition} (@emph{ArrayName},@dots{})
                   3637: @end example
                   3638: 
                   3639: In the exclusive form, writes all local variables @emph{except} those specified in the list of @emph{ArrayName}s to @code{$IO} if the optional @emph{postcondition} is @emph{true} or omitted.
                   3640: 
                   3641: 
                   3642: @node Structured System Variables
                   3643: @chapter Structured System Variables
                   3644: @cindex variables, structured system
                   3645: @cindex structured system variables
                   3646: @cindex SSVNs
                   3647: 
                   3648: @menu
                   3649: * ^$CHARACTER::                         Character set information.
                   3650: * ^$DEVICE::                            Device information.
                   3651: * ^$DISPLAY::                           Information about graphic display.
                   3652: * ^$EVENT::                             Information supplied about a synchronous or asynchronous event.
                   3653: * ^$GLOBAL::                            Information about M globals.
                   3654: * ^$JOB::                               Information about and control of FreeM jobs.
                   3655: * ^$LOCK::                              Information about the FreeM lock table.
                   3656: * ^$OBJECT::                            Information about FreeM objects.
                   3657: * ^$ROUTINE::                           Information about FreeM routines.
                   3658: * ^$SYSTEM::                            Information about the running system.
                   3659: * ^$WINDOW::                            Configuration of MWAPI windows.
                   3660: * ^$ZPROCESS::                          Information about and control of system processes.
                   3661: * ^$ZRPI::                              Information about and control of Raspberry Pi GPIO pins.
                   3662: @end menu
                   3663: 
                   3664: SSVN subscripts are each described in the following format:
                   3665: 
                   3666: @table @asis
                   3667: @item @code{@emph{<ssvn-subscript-name>}} +/-R +/-U +/-D
                   3668: @end table
                   3669: 
                   3670: The R, U, and D flags represent Read, Update, and Delete. A minus sign indicates that the given operation is @emph{not} allowed, and a plus sign indicates that the given operation @emph{is} allowed.
                   3671: 
                   3672: @node ^$CHARACTER
                   3673: @section ^$CHARACTER
                   3674: @cindex ^$CHARACTER
                   3675: @cindex structured system variables, ^$CHARACTER
                   3676: 
                   3677: Exposes character set information. As FreeM currently only supports the @code{M} character set, the first subscript of @code{^$CHARACTER} must always be @code{"M"}.
                   3678: 
                   3679: The following values for the second subscript are supported:
                   3680: 
                   3681: @table @asis
                   3682: 
                   3683: @item @code{IDENT} +R -U -D
                   3684: Returns the empty string.
                   3685: 
                   3686: @item @code{COLLATE} +R -U -D
                   3687: Returns the empty string.
                   3688: 
                   3689: @item @code{INPUT} +R -U -D
                   3690: Returns the empty string if the third subscript is @code{M}, otherwise, raises error @code{M38}.
                   3691: 
                   3692: @item @code{OUTPUT} +R -U -D
                   3693: Returns the empty string if the third subscript is @code{M}, otherwise, raises error @code{M38}.
                   3694: 
                   3695: @end table
                   3696: 
                   3697: @node ^$DEVICE
                   3698: @section ^$DEVICE
                   3699: @cindex ^$DEVICE
                   3700: @cindex structured system variables, ^$DEVICE
                   3701: 
                   3702: FreeM implements several important pieces of functionality in the @code{^$DEVICE} SSVN.
                   3703: 
                   3704: The first subscript of @code{^$DEVICE} represents the I/O channel of an @code{OPEN}ed device.
                   3705: 
                   3706: The following values for the second subscript are supported:
                   3707: 
                   3708: @table @asis
                   3709: 
                   3710: @item @code{$DEVICE}
                   3711: Returns the value of @code{$DEVICE} for the specified I/O channel.
                   3712: 
                   3713: @item @code{$X} +R -U -D
                   3714: Returns the horizontal cursor position of a terminal device. Only valid if the I/O channel is @code{0}.
                   3715: 
                   3716: @item @code{$Y} +R -U -D
                   3717: Returns the vertical cursor position of a terminal device. Only valid if the I/O channel is @code{0}.
                   3718: 
                   3719: @item @code{ROWS} +R -U -D
                   3720: Returns the number of character rows on the terminal device. Only valid if the I/O channel is @code{0}.
                   3721: 
                   3722: @item @code{COLUMNS} +R -U -D
                   3723: Returns the number of character columns on the terminal device. Only valid if the I/O channel is @code{0}.
                   3724: 
                   3725: @item @code{CHARACTER} +R -U -D
                   3726: Returns the character set of the specified I/O channel; always @code{M} in the current implementation.
                   3727: 
                   3728: @item @code{INPUT_BUFFER} +R +U -D
                   3729: Returns or sets the contents of the input buffer for the specified I/O channel. Data populated in this node will remain in the buffer until subsequent @code{READ} command(s) remove it. This can be used to perform input buffer stuffing, i.e., to fill out an interactive form programmatically.
                   3730: 
                   3731: @item @code{NAME} +R -U -D
                   3732: Returns the operating system's name for the file, device, or socket attached to the specified I/O channel.
                   3733: 
                   3734: @item @code{FD} +R -U -D
                   3735: Returns the UNIX file descriptor of the specified I/O channel.
                   3736: 
                   3737: @item @code{MODE} +R -U -D
                   3738: Returns one of @code{READ}, @code{WRITE}, @code{READWRITE}, or @code{APPEND}, depending on the mode in which the specified I/O channel was opened.
                   3739: 
                   3740: @item @code{EOF} +R -U -D
                   3741: Returns @code{1} if the I/O channel has encountered an end-of-file condition; @code{0} otherwise. Only valid if the I/O channel is connected to a sequential file.
                   3742: 
                   3743: @item @code{LENGTH} +R -U -D
                   3744: Returns the length of the file connected to the I/O channel. Only valid if the I/O channel is connected to a sequential file.
                   3745: 
                   3746: @item @code{NAMESPACE} +R -U -D
                   3747: Returns the current @emph{mnemonic-space} in use for the referenced I/O channel. Always @code{X364} for terminals and blank for sequential files.
                   3748: 
                   3749: @item @code{TYPE} +R -U -D
                   3750: Returns either @code{1,FILE}, @code{2,SOCKET}, or @code{4,TERMINAL}, depending on the device type associated with the specified I/O channel.
                   3751: 
                   3752: @item @code{OPTIONS} -R -U -D
                   3753: The following subscripts reside beneath @code{^$DEVICE(<io-channel>,"OPTIONS")}, and this subscript may not be accessed without one of the following third-level subscripts being specified:
                   3754: 
                   3755: @table @asis
                   3756: 
                   3757: @item @code{DSW} +R +U -D
                   3758: Sets or returns the current @emph{Device Status Word} controlling terminal characteristics. Only valid for I/O channel 0.
                   3759: 
                   3760: @item @code{TERMINATOR} +R +U -D
                   3761: Sets or returns the @code{READ} terminator for the specified I/O channel. Must be either @code{$C(13,10)} or @code{$C(10)}. Currently only supported for socket devices (those having an I/O channel of 100-255).
                   3762: 
                   3763: @item @code{TERMID} +R -U -D
                   3764: Returns the type of terminal connected to channel 0. Only valid for I/O channel 0.
                   3765: 
                   3766: @item @code{ECHO} +R +U -D
                   3767: Enables or disables local echo of characters typed in a @code{READ} command. Only valid for I/O channel 0. Corresponds to bit 0 of the Device Status Word.
                   3768: 
                   3769: @item @code{DELMODE} +R +U -D
                   3770: Enables or disables visual backspace during a @code{READ} command. Only valid for I/O channel 0. Corresponds to bit 2 of the Device Status Word.
                   3771: 
                   3772: @item @code{ESCAPE} +R +U -D
                   3773: Enables or disables escape sequence processing during a @code{READ} command. Only valid for I/O channel 0. Corresponds to bit 6 of the Device Status Word.
                   3774: 
                   3775: @item @code{CONVUPPER} +R +U -D
                   3776: Enables or disables automatic conversion to uppercase of alphabetical characters during a @code{READ} command. Only valid for I/O channel 0. Corresponds to bit 14 of the Device Status Word.
                   3777: 
                   3778: @item @code{DELEMPTY} +R +U -D
                   3779: Enables or disables the automatic deletion of empty strings supplied to a @code{READ} command. Only valid for I/O channel 0. Corresponds to bit 19 of the Device Status Word.
                   3780: 
                   3781: @item @code{NOCTRLS} +R +U -D
                   3782: TBD. Only valid for I/O channel 0. Corresponds to bit 20 of the Device Status Word.
                   3783: 
                   3784: @item @code{CTRLOPROC} +R +U -D
                   3785: Enables or disables @emph{Ctrl-O} processing during @code{READ} commands. Only valid for I/O channel 0. Corresponds to bit 21 of the Device Status Word.
                   3786: 
                   3787: @item @code{NOTYPEAHEAD} +R +U -D
                   3788: Enables or disables typeahead buffering during @code{READ} commands. Only valid for I/O channel 0. Corresponds to bit 25 of the Device Status Word.
                   3789: @end table
                   3790: @end table
                   3791: 
                   3792: @emph{Example}
                   3793: 
                   3794: The following example M code opens @code{/etc/freem.conf} and reads its contents line-by-line until the end of the file is reached.
                   3795: 
                   3796: @example
                   3797:  SET ^$JOB($JOB,"IOPATH")="/etc"   ; set I/O path to /etc
                   3798:  OPEN 1:"freem.conf/r" ; open freem.conf for reading
                   3799:  ;
                   3800:  ; read until we run out of lines
                   3801:  ;
                   3802:  FOR  USE 1 READ LINE USE 0 QUIT:^$DEVICE(1,"EOF")  D
                   3803:  . WRITE LINE,!
                   3804:  ;
                   3805:  CLOSE 1
                   3806:  QUIT
                   3807: @end example
                   3808: 
                   3809: @node ^$DISPLAY
                   3810: @section ^$DISPLAY
                   3811: @cindex ^$DISPLAY
                   3812: @cindex structured system variables, ^$DISPLAY
                   3813: 
                   3814: Provides information about the specified graphical display. The first subscript corresponds to a display number, which is an integer value, often corresponding to the current value of the @code{$PDISPLAY} ISV.
                   3815: 
                   3816: The following second-level subscripts and specified descendant subscripts are supported:
                   3817: 
                   3818: @table @asis
                   3819: 
                   3820: @item @code{CLIPBOARD} +R +U +D
                   3821: Retrieves, sets, or erases the contents of the system clipboard.
                   3822: 
                   3823: @item @code{PLATFORM} +R -U -D
                   3824: Retrieves the name and version of the underlying window system platform.
                   3825: 
                   3826: @item @code{SIZE} +R -U -D
                   3827: Retrieves the display resolution of the specified graphical display. For instance, a 1080p display would have a @code{SIZE} value of @code{1920,1080}.
                   3828: 
                   3829: @item @code{SPECTRUM} +R -U -D
                   3830: Retrieves the color depth (number of colors supported) of the specified graphical display.
                   3831: 
                   3832: @item @code{COLORTYPE} +R -U -D
                   3833: Always returns @code{COLOR}, as monochrome and grayscale displays are not yet supported in FreeM.
                   3834: 
                   3835: @item @code{UNITS} +R -U -D
                   3836: Returns the measurement unit of the specified display, i.e., @code{PIXEL}.
                   3837: 
                   3838: @item @code{TYPEFACE} +R -U -D
                   3839: The third-level subscripts beneath this subscript represent a list of font families available on this display. The fourth level subscript is a list of sizes supported for the specified typeface, or @code{0} for vector typefaces, such as TrueType, OpenType, and Adobe Type 1 fonts.
                   3840: 
                   3841: @end table
                   3842: 
                   3843: @node ^$EVENT
                   3844: @section ^$EVENT
                   3845: @cindex ^$EVENT
                   3846: @cindex structured system variables, ^$EVENT
                   3847: 
                   3848: The @code{^$EVENT} SSVN is not yet implemented.
                   3849: 
                   3850: @node ^$GLOBAL
                   3851: @section ^$GLOBAL
                   3852: @cindex ^$GLOBAL
                   3853: @cindex structured system variables, ^$GLOBAL
                   3854: 
                   3855: The @code{^$GLOBAL} structured system variable provides information about M globals. The first-level subscript is a global name, sans the leading caret symbol.
                   3856: 
                   3857: The following second-level subscripts are supported:
                   3858: 
                   3859: @table @asis
                   3860: 
                   3861: @item @code{BYTES} +R -U -D
                   3862: Returns the number of bytes this global occupies in fixed storage.
                   3863: 
                   3864: @item @code{BLOCKS} +R -U -D
                   3865: Returns the number of blocks contained in this global.
                   3866: 
                   3867: @item @code{BLOCKSIZE} +R -U -D
                   3868: Returns the size of data blocks for this global. Currently, FreeM only supports 1024-byte blocks.
                   3869: 
                   3870: @item @code{FILE} +R -U -D
                   3871: Returns the full filesystem path to the data file where this global resides in fixed storage.
                   3872: 
                   3873: @item @code{NAMESPACE} +R +U +D
                   3874: Returns or sets the name of the FreeM namespace to which this global belongs. @code{SET}ting this node creates a mapping for the specified global name to a non-default namespace. @code{KILL}ing this node restores the mapping configuration for the specified global to the default.
                   3875: 
                   3876: @end table
                   3877: 
                   3878: @node ^$JOB
                   3879: @section ^$JOB
                   3880: @cindex ^$JOB
                   3881: @cindex structured system variables, ^$JOB
                   3882: 
                   3883: FreeM fully implements @code{^$JOB} per ANSI X11.1-1995, as well as several extensions proposed in the M Millennium Draft Standard.
                   3884: 
                   3885: The first subscript of @code{^$JOB} represents the @code{$JOB} of the process.
                   3886: 
                   3887: If you @code{KILL} a first-level subscript of @code{^$JOB}, the @code{SIGTERM} signal will be sent to the corresponding UNIX process, causing pending transactions to be rolled back and the process to be terminated. If the targeted process is in direct mode, the user will be prompted with options of either rolling back or committing any pending transactions.
                   3888: 
                   3889: The following subscripts are supported:
                   3890: 
                   3891: @table @asis
                   3892: 
                   3893: @item @code{GVNDEFAULT} +R +U +D
                   3894: Contains a default expression to be evaluated if a global variable access attempt results in an @code{M7} error.
                   3895: 
                   3896: Equivalent to wrapping all global accesses in @code{$GET(@emph{global-name},@emph{string-expr})}.
                   3897: 
                   3898: @item @code{LVNDEFAULT} +R +U +D
                   3899: Contains a default expression to be evaluated if a local variable access attempt results in an @code{M6} error.
                   3900: 
                   3901: Equivalent to wrapping all local accesses in @code{$GET(@emph{global-name},@emph{string-expr})}.
                   3902: 
                   3903: @item @code{LVNQOVAL} +R +U +D
                   3904: Contains the data value (if any) at the subscripted local variable reference from the most recent @code{$ORDER} or @code{$QUERY} operation.
                   3905: 
                   3906: This node is useful for code that uses @code{$ORDER} or @code{$QUERY} heavily in loops that retrieve successive data values, as it will prevent an additional symbol table scan that would result from retrieving the data value in the usual way, thus improving application performance. However, this optimization comes at the cost of compatibility with other M implementations.
                   3907: 
                   3908: @item @code{GVNQOVAL} +R +U +D
                   3909: Contains the data value (if any) at the subscripted global variable reference from the most recent @code{$ORDER} or @code{$QUERY} operation.
                   3910: 
                   3911: This node is useful for code that uses @code{$ORDER} or @code{$QUERY} heavily in loops that retrieve successive data values, as it will prevent an additional data file scan that would result from retrieving the data value in the usual way, thus improving application performance. However, this optimization comes at the cost of compatibility with other M implementations.
                   3912: 
                   3913: @item @code{ZCOMMANDS} +R +U -D
                   3914: Contains a space-delimited list of @code{Z}-commands to be treated as intrinsic. Any @code{Z}-command not appearing in this list will be treated as a user-defined command.
                   3915: 
                   3916: For instance, if command @code{ZFOO} does @emph{not} appear in this list, FreeM will attempt to run @code{^%ZFOO} as a subroutine when the @code{ZFOO} command is encountered in program code.
                   3917: 
                   3918: If you remove a command from this list, you may provide your own private M implementation of the command in the manner described above.
                   3919: 
                   3920: If an argument is passed to a @code{Z}-command you implement in M, it is made available to your M code in a variable whose name is specified in @code{^$JOB($JOB,"ZCOMMAND_ARGUMENT_NAME")}, which defaults to @code{%}.
                   3921: 
                   3922: @item @code{PIPE_GLVN} +R +U -D
                   3923: Contains an M local or global variable to be used as standard input or standard output for the external shell commands run by @code{!<} and @code{!>}.
                   3924: 
                   3925: @item @code{ZCOMMAND_ARGUMENT_NAME} +R +U -D
                   3926: Returns or sets the variable name in which arguments to user-defined @code{Z}-commands are passed. Defaults to @code{%}.
                   3927: 
                   3928: @item @code{ZFUNCTIONS} +R +U -D
                   3929: Contains a space-delimited list of @code{Z} functions to be treated as intrinsic. Any @code{Z} function not appearing in this list will be treated as a user-defined extrinsic function.
                   3930: 
                   3931: For instance, if function @code{$ZFOO} does @emph{not} appear in this list, FreeM will attempt to return the value of @code{$$^%ZFOO} called as an extrinsic function.
                   3932: 
                   3933: If you remove a function from this list, you may provide your own private M implementation of the function in the manner described above.
                   3934: 
                   3935: @item @code{ZSVS} +R +U -D
                   3936: Contains a space-delimited list of @code{Z} special variables to be treated as intrinsic. Any @code{Z} special variable  not appearing in this list will be treated as a user-defined extrinsic function taking no arguments.
                   3937: 
                   3938: For instance, if the special variable @code{$ZFOO} does @emph{not} appear in this list, FreeM will attempt to return the value of @code{$$^%ZFOO} called as an extrinsic function.
                   3939: 
                   3940: If you remove a built-in special variable from this list, you may provide your own private M implementation of the special variable in the manner described above.
                   3941: 
                   3942: @item @code{BREAK_HANDLER} +R +U -D
                   3943: Contains M code to be executed when the @code{BREAK} command is run.
                   3944: 
                   3945: @item @code{ROUTINE_BUFFER_SIZE} +R +U -D
                   3946: Returns or sets the number of bytes allocated to each routine buffer. If @code{ROUTINE_BUFFER_AUTO_ADJUST} is set to @code{0}, this determines the maximum size of routines that FreeM will execute.
                   3947: 
                   3948: @item @code{ROUTINE_BUFFER_COUNT} +R +U -D
                   3949: Returns or sets the number of routine buffers that FreeM will store in memory concurrently. Raising this value will increase memory usage, but will also increase performance if your applications call many different routines repeatedly.
                   3950: 
                   3951: @item @code{ROUTINE_BUFFER_AUTO_ADJUST} +R +U -D
                   3952: Determines whether or not the size of routine buffers will be automatically adjusted at runtime. If set to @code{0}, routine buffers will be fixed to the byte size specified in @code{ROUTINE_BUFFER_SIZE} and may be manually resized using @code{ROUTINE_BUFFER_SIZE}. If set to @code{1}, routine buffers will grow automatically as necessary.
                   3953: 
                   3954: @item @code{SYMBOL_TABLE_SIZE} +R +U -D
                   3955: Returns or sets the number of bytes allocated to each of the two FreeM symbol tables. If @code{SYMBOL_TABLE_AUTO_ADJUST} is @code{1}, this value is treated as a default, initial size. If @code{SYMBOL_TABLE_AUTO_ADJUST} is @code{0}, this value controls the fixed size of the two symbol tables.
                   3956: 
                   3957: @item @code{SYMBOL_TABLE_AUTO_ADJUST} +R +U -D
                   3958: Determines whether or not the size of the two FreeM symbol tables will be automatically adjusted at runtime. If set to @code{0}, the symbol table will be fixed to the byte size specified in @code{SYMBOL_TABLE_SIZE} and may be manually resized by modifying @code{SYMBOL_TABLE_SIZE}. If set to @code{1}, the two symbol tables will grow automatically as necessary.
                   3959: 
                   3960: 
                   3961: @item @code{USER_DEFINED_ISV_TABLE_SIZE} +R +U -D
                   3962: Returns or sets the number of bytes allocated to the FreeM user-defined intrinsic special variable table. If @code{USER_DEFINED_ISV_TABLE_AUTO_ADJUST} is @code{1}, this value is treated as a default, initial size. If @code{USER_DEFINED_ISV_TABLE_AUTO_ADJUST} is @code{0}, this value controls the fixed byte size of the user-defined intrinsic special variable table.
                   3963: 
                   3964: @item @code{USER_DEFINED_ISV_TABLE_AUTO_ADJUST} +R +U -D
                   3965: Determines whether or not the size of the FreeM user-defined intrinsic special variable table will be automatically adjusted at runtime. If set to @code{0}, the user-defined ISV table will be fixed to the byte size specified in @code{USER_DEFINED_ISV_TABLE_SIZE} and may be manually resized by modifying @code{USER_DEFINED_ISV_TABLE_SIZE}. If set to @code{1}, the user-defined ISV table will grow automatically as necessary.
                   3966: 
                   3967: @item @code{GVN_UNIQUE_CHARS} +R +U -D
                   3968: Returns or sets the number of characters of a global name that make it unique, from 1 to 255.
                   3969: 
                   3970: @item @code{GVN_CASE_SENSITIVE} +R +U -D
                   3971: Returns or sets the case sensitivity of global names. If set to @code{0}, global names are case-insensitive. If set to @code{1}, global names are case-sensitive.
                   3972: 
                   3973: @item @code{GVN_NAME_SUB_LENGTH} +R +U -D
                   3974: Returns or sets the maximum number of characters of a global name plus all of its subscripts, from 1-255.
                   3975: 
                   3976: @item @code{GVN_SUB_LENGTH} +R +U -D
                   3977: Returns or sets the maximum number of characters of a single global subscript, from 1-255.
                   3978: 
                   3979: @item @code{SINGLE_USER} +R +U -D
1.27      snw      3980: If set to @code{1}, FreeM will skip all file locking operations on globals. If set to @code{0}, FreeM will enforce file locking on both.
1.1       snw      3981: 
1.27      snw      3982: Setting @code{SINGLE_USER} to @code{1} will improve FreeM performance, but you must @emph{ONLY} use this on systems where you are absolutely sure that only one FreeM process will run at any given time, as running multiple instances of FreeM concurrently when any of them are set to @code{SINGLE_USER} mode @emph{will} cause global data corruption.
1.1       snw      3983: 
                   3984: @item @code{CHARACTER} +R -U -D
                   3985: Returns the character set of the job.
                   3986: 
                   3987: @item @code{CWD} +R +U -D
                   3988: Returns or sets the current working directory of the job.
                   3989: 
                   3990: @item @code{OPEN} +R -U -D
                   3991: The @code{^$JOB($JOB,"OPEN",<channel>} subscripts list the open I/O channels in the specified job.
                   3992: 
                   3993: @item @code{BERKELEYDB,FLUSH_THRESHOLD} +R +U -D
                   3994: Returns or sets the number of write operations that will be cached in the BerkeleyDB global handler prior to flushing BerkeleyDB's cache to disk.
                   3995: 
                   3996: @item @code{EVENT} +R +U +D
                   3997: The subtree contained under @code{^$JOB($J,"EVENT")} defines asynchronous event handlers for the current job. Please see @emph{Asynchronous Event Handling} for more information.
                   3998: 
                   3999: @item @code{GLOBAL} +R -U -D
                   4000: Returns the global environment of the job.
                   4001: 
                   4002: @item @code{IOPATH} +R +U -D
                   4003: Returns or sets the @emph{I/O path} to be used by the @code{OPEN} command.
                   4004: 
                   4005: @item @code{PRIORITY} +R +U -D
                   4006: Returns or sets the @emph{nice} value of the FreeM job.
                   4007: 
                   4008: @item @code{REVSTR} +R +U -D
                   4009: When set to 1, allows @code{$EXTRACT} to accept negative values.
                   4010: 
                   4011: @item @code{ROUTINE} +R -U -D
                   4012: Returns the name of the routine currently being executed by the job.
                   4013: 
                   4014: @item @code{SYMTAB} +R +U -D
                   4015: Returns or sets the current local variable symbol table in use.
                   4016: 
                   4017: FreeM supports two unique and independent symbol tables, allowing FreeM programs to maintain two independent sets of identically- or differently-named local variables per process.
                   4018: 
                   4019: The default symbol table is @code{0}, and the alternate symbol table is @code{1}, corresponding to the valid values for @code{^$JOB($JOB,"SYMTAB")}.
                   4020: 
                   4021: Setting this subscript to values other than @code{0} or @code{1} will result in a @code{ZINVEXPR} error.
                   4022: 
                   4023: @item @code{$PDISPLAY} +R -U -D
                   4024: Returns the value of @code{$PDISPLAY} for the job.
                   4025: 
                   4026: @item @code{$PRINCIPAL} +R -U -D
                   4027: Returns the value of @code{$PRINCIPAL} for the job.
                   4028: 
                   4029: @item @code{$TLEVEL} +R -U -D
                   4030: Returns the current transaction level (value of @code{$TLEVEL} for the job.
                   4031: 
                   4032: @item @code{$IO} +R -U -D
                   4033: Returns the current value of @code{$IO} for the job.
                   4034: 
                   4035: @item @code{USER} +R -U -D
                   4036: Returns the UID of the user owning the job.
                   4037: 
                   4038: @item @code{GROUP} +R -U -D
                   4039: Returns the GID of the group owning the job.
                   4040: 
                   4041: @item @code{NAMESPACE} +R +U -D
                   4042: Returns or sets the name of the job's currently-active namespace.
                   4043: 
                   4044: @item @code{MATH} +R +U -D
                   4045: Returns or sets the mode in which decimal comparisons and arithmetic calculations are conducted. Valid values are @code{FIXED}, for fixed-point decimals having up to 20,000 digits of precision, as determined by the @code{$ZPRECISION} intrinsic special variable, and @code{IEEE754}, to use IEEE 754 floating-point decimals. When in @code{IEEE754} mode, floating-point numbers support up to 16 digits of numeric precision.
                   4046: 
                   4047: @code{IEEE754} mode will make mathematical calculations significantly faster, especially when accelerated by a floating-point processor, at the expense of precision and accuracy.
                   4048: 
                   4049: @code{FIXED} mode is recommended for financial calculations, or where precision and accuracy are valued over performance. @code{FIXED} is the default mode of FreeM operation.
                   4050: 
                   4051: Attempting to @code{SET} this node to values other than @code{FIXED} or @code{IEEE754} will set @code{$ECODE} to @code{M29}.
                   4052: 
                   4053: @end table
                   4054: 
                   4055: @node ^$LOCK
                   4056: @section ^$LOCK
                   4057: @cindex ^$LOCK
                   4058: @cindex structured system variables, ^$LOCK
                   4059: 
                   4060: The first-level subscript of @code{^$LOCK} is a lock name. The value at each node is the PID which owns the lock, a comma, and the lock counter for the locked resource.
                   4061: 
                   4062: Attempting to @code{SET} or @code{KILL} any node in @code{^$LOCK} will raise error @code{M29}.
                   4063: 
                   4064: @node ^$OBJECT
                   4065: @section ^$OBJECT
                   4066: @cindex ^$OBJECT
                   4067: @cindex structured system variables, ^$OBJECT
                   4068: 
                   4069: @node ^$ROUTINE
                   4070: @section ^$ROUTINE
                   4071: @cindex ^$ROUTINE
                   4072: @cindex structured system variables, ^$ROUTINE
                   4073: 
                   4074: The @code{^$ROUTINE} SSVN exposes a list of routines available in the current FreeM namespace, as well as additional attributes further describing each routine.
                   4075: 
                   4076: The first-level subscript is the name of a FreeM routine minus the leading caret symbol.
                   4077: 
                   4078: The following second-level subscripts are supported:
                   4079: 
                   4080: @table @asis
                   4081: 
                   4082: @item @code{CHARACTER} +R -U -D
                   4083: Returns the character set of the routine.
                   4084: 
                   4085: @item @code{NAMESPACE} +R -U -D
                   4086: Returns the name of the FreeM namespace in which the routine resides.
                   4087: 
                   4088: @item @code{PATH} +R -U -D
                   4089: Returns the full filesystem path to the routine in fixed storage.
                   4090: 
                   4091: @end table
                   4092: 
                   4093: @node ^$SYSTEM
                   4094: @section ^$SYSTEM
                   4095: @cindex ^$SYSTEM
                   4096: @cindex structured system variables, ^$SYSTEM
                   4097: 
                   4098: The @code{^$SYSTEM} SSVN exposes system-level implementation details.
                   4099: 
                   4100: The following first-level subscripts are supported:
                   4101: 
                   4102: @table @asis
                   4103: 
                   4104: @item @code{DEFPSIZE} +R -U -D
                   4105: Returns the default size in bytes of the symbol table and routine buffer memory partition.
                   4106: 
                   4107: @item @code{DEFUDFSVSIZ} +R -U -D
                   4108: Returns the default size in bytes of the user-defined intrinsic special variable table.
                   4109: 
                   4110: @item @code{DEFNSIZE} +R -U -D
                   4111: Returns the default size of the @code{NEW} stack, in number of entries.
                   4112: 
                   4113: @item @code{MAXNO_OF_RBUF} +R -U -D
                   4114: Returns the maximum number of routine buffers.
                   4115: 
                   4116: @item @code{DEFNO_OF_RBUF} +R -U -D
                   4117: Returns the default number of routine buffers.
                   4118: 
                   4119: @item @code{DEFPSIZE0} +R -U -D
                   4120: Returns the default size in bytes of each routine buffer.
                   4121: 
                   4122: @item @code{NO_GLOBLS} +R -U -D
                   4123: Returns the maximum number of globals that can be concurrently opened.
                   4124: 
                   4125: @item @code{NO_OF_GBUF} +R -U -D
                   4126: Returns the number of global buffers.
                   4127: 
                   4128: @item @code{NESTLEVLS} +R -U -D
                   4129: Returns the depth of the @code{DO}, @code{FOR}, @code{XECUTE} stack.
                   4130: 
                   4131: @item @code{PARDEPTH} +R -U -D
                   4132: Returns the maximum depth of the parser's parameter stack.
                   4133: 
                   4134: @item @code{PATDEPTH} +R -U -D
                   4135: Returns the maximum number of @emph{patatom}s in each pattern.
                   4136: 
                   4137: @item @code{TRLIM} +R -U -D
                   4138: Returns the trace limit of the @code{BUILTIN} global handler.
                   4139: 
                   4140: @item @code{ARGS_IN_ESC} +R -U -D
                   4141: Returns the maximum number of arguments in a terminal escape sequence.
                   4142: 
                   4143: @item @code{ZTLEN} +R -U -D
                   4144: Returns the maximum length of @code{$ZTRAP}.
                   4145: 
                   4146: @item @code{FUNLEN} +R -U -D
                   4147: Returns the maximum length of the @code{$ZF} (function key) variable.
                   4148: 
                   4149: @item @code{NAME_LENGTH} +R -U -D
                   4150: Returns the maximum length of variable names in the current FreeM build. Compatible with the same SSVN node in @emph{Reference Standard M}
                   4151: 
                   4152: @item @code{STRING_MAX} +R -U -D
                   4153: Returns the maximum length of character strings in the current FreeM build. Compatible with the same SSVN node in @emph{Reference Standard M}
                   4154: 
                   4155: @item @code{$NEXTOK} +R -U -D
                   4156: Returns a value indicating whether or not the @code{$NEXT} intrinsic function is allowed. In FreeM, @code{$NEXT} is always enabled, and this SSVN is provided solely for compatibility with @emph{Reference Standard M}. Thus, this SSVN node always returns @code{1}.
                   4157: 
                   4158: @item @code{EOK} +R -U -D
                   4159: Returns a value indicating whether or not @code{E} notation for exponents is allowed. In FreeM, this feature is always enabled, and this SSVN is provided solely for compatibility with @emph{Reference Standard M}. Thus, this SSVN node always returns @code{1}.
                   4160: 
                   4161: @item @code{OFFOK} +R -U -D
                   4162: Returns a value indicating whether or not offsets are allowed in @code{DO} and @code{GOTO}. In FreeM, this feature is always enabled, and this SSVN is provided solely for compatibility with @emph{Reference Standard M}. Thus, this SSVN node always returns @code{1}.
                   4163: 
                   4164: @item @code{BIG_ENDIAN} +R -U -D
                   4165: Returns a 1 if FreeM is running on a big-endian platform, or a 0 otherwise. Compatible with the same SSVN node in @emph{Reference Standard M}.
                   4166: 
                   4167: @item @code{NAMESPACE} +R -U -D
                   4168: The descendant subscripts of this node list each namespace in the current FreeM environment.
                   4169: 
                   4170: @item @code{MAPPINGS,GLOBAL} +R -U -D
                   4171: Descendant subscripts of this node represent global name mappings set in @code{^$GLOBAL(@emph{gvn},"NAMESPACE")}
                   4172: 
                   4173: @end table
                   4174: 
                   4175: @node ^$WINDOW
                   4176: @section ^$WINDOW
                   4177: @cindex ^$WINDOW
                   4178: @cindex structured system variables, ^$WINDOW
                   4179: 
                   4180: The @code{^$WINDOW} SSVN has no nodes yet defined. However, completing a @code{MERGE} to this SSVN will cause MWAPI-ish things to happen, and further work is proceeding on MWAPI implementation.
                   4181: 
                   4182: @node ^$ZPROCESS
                   4183: @section ^$ZPROCESS
                   4184: @cindex ^$ZPROCESS
                   4185: @cindex structured system variables, ^$ZPROCESS
                   4186: 
                   4187: Provides access to @code{procfs}, which is a filesystem-like abstraction for UNIX process metadata contained in @code{/proc}, as well as features for examining and controlling the state of processes external to the FreeM interpreter.
                   4188: 
                   4189: The first subscript always represents the @emph{process ID} of the external process being acted upon.
                   4190: 
                   4191: The following values for the second subscript are supported:
                   4192: 
                   4193: 
                   4194: @table @asis
                   4195: 
                   4196: @item @code{EXISTS} +R -U -D
                   4197: Returns 1 if the referenced process exists; 0 otherwise.
                   4198: 
                   4199: @item @code{ATTRIBUTE} +R -U -D
                   4200: Exposes the @code{/proc} files as descendant subscripts, i.e., @code{WRITE ^$ZPROCESS(2900,"ATTRIBUTE","cmdline"),!} would print the initial command line used to invoke process ID 2900. Note that the third subscript (the immediate descendant of the @code{ATTRIBUTE} subscript) is case sensitive.
                   4201: 
                   4202: @item @code{SIGNAL} -R +U -D
                   4203: Allows signals to be sent to the referenced process. The following subscript is an integer value corresponding to the desired signal number. You may obtain a list of signal numbers on most UNIX systems with the command @code{kill -l}.
                   4204: 
                   4205: The constants @code{%SYS.SIGNAL.HUP}, @code{%SYS.SIGNAL.INT}, @code{%SYS.SIGNAL.KILL}, and @code{%SYS.SIGNAL.TERM} are provided for convenient use of this SSVN subscript.
                   4206: 
                   4207: @end table
                   4208: 
                   4209: @node ^$ZRPI
                   4210: @section ^$ZRPI
                   4211: @cindex ^$ZRPI
                   4212: @cindex structured system variables, ^$ZRPI
                   4213: 
                   4214: The @code{^$ZRPI} structured system variable provides easy access to general-purpose input/output (GPIO) pins on Raspberry Pi single-board computers.
                   4215: 
                   4216: To initialize the GPIO subsystem, @code{SET ^$ZRPI("INITIALIZE")=1}.
                   4217: 
                   4218: Individual pins are accessed through @code{^$ZRPI("GPIO",<pin>,...)}, where @code{<pin>} represents the desired pin number. Descendant subscripts of @code{^$ZRPI("GPIO",<pin>)} are as follows:
                   4219: 
                   4220: @table @asis
                   4221: 
                   4222: @item @code{MODE} +R +U -D
                   4223: Represents the operating mode of the selected pin. One of @code{INPUT}, @code{OUTPUT}, @code{PWM_OUTPUT}, or @code{GPIO_CLOCK}.
                   4224: 
                   4225: @item @code{DIGITAL} +R +U -D
                   4226: Reads or writes the selected pin digitally. The value is limited to @code{1} or @code{0}.
                   4227: 
                   4228: @item @code{ANALOG} +R +U -D
                   4229: Reads or writes the selected pin in an analog fashion. The value represents analog voltage.
                   4230: 
                   4231: @end table
                   4232: 
                   4233: @node Operators
                   4234: @chapter Operators
                   4235: 
                   4236: @menu
                   4237: * Unary +::                     Force a value to positive.
                   4238: * Unary -::                     Force a value to negative.
                   4239: * +::                           Add.
                   4240: * +=::                          Add and assign.
                   4241: * ++::                          Postfix increment.
                   4242: * -::                           Subtract.
                   4243: * -=::                          Subtract and assign.
                   4244: * --::                          Postfix decrement.
                   4245: * *::                           Multiply.
                   4246: * *=::                          Multiply and assign.
                   4247: * /::                           Divide.
                   4248: * /=::                          Divide and assign.
                   4249: * \::                           Integer divide.
                   4250: * \=::                          Integer divide and assign.
                   4251: * #::                           Modulo.
                   4252: * #=::                          Modulo and assign.
                   4253: * **::                          Exponentiate.
                   4254: * **=::                         Exponentiate and assign.
                   4255: * <::                           Less than.
                   4256: * <=::                          Less than or equal to.
                   4257: * >::                           Greater than.
                   4258: * >=::                          Greater than or equal to.
                   4259: * _::                           Concatenate.
                   4260: * _=::                          Concatenate and assign.
                   4261: * =::                           Equals.
                   4262: * [::                           Contains.
                   4263: * ]::                           Follows.
                   4264: * ]]::                          Sorts after.
                   4265: * ?::                           Pattern match.
                   4266: * &::                           Logical AND.
                   4267: * ! (Operator)::                Logical OR.
                   4268: * '::                           Logical NOT.
                   4269: * @@ (Operator)::               Indirect
                   4270: @end menu
                   4271: 
                   4272: @node Unary +
                   4273: @section Unary +
                   4274: @cindex operators, unary +
                   4275: 
                   4276: Forces a number to positive, whether positive or negative. Also forces numeric coercion of strings.
                   4277: 
                   4278: @node Unary -
                   4279: @section Unary -
                   4280: @cindex operators, unary -
                   4281: 
1.28      snw      4282: Forces a number to negative, whether positive or negative. Also forces numeric coercion of strings.
                   4283: 
1.1       snw      4284: @node +
                   4285: @section + (Add)
                   4286: @cindex operators, +
                   4287: 
1.28      snw      4288: @emph{Syntax}
                   4289: 
                   4290: @example
                   4291: S X=1+2 ; => 3
                   4292: @end example
                   4293: 
                   4294: Adds numbers together.
                   4295: 
1.1       snw      4296: @node +=
                   4297: @section += (Add/Assign)
                   4298: @cindex operators, +=
                   4299: 
1.28      snw      4300: @emph{Syntax}
                   4301: 
                   4302: @example
                   4303: S X=5
                   4304: S X+=3 ; => 8
                   4305: @end example
                   4306: 
                   4307: Increments the variable on the LHS by the value on the RHS.
                   4308: 
1.1       snw      4309: @node ++
                   4310: @section ++ (Postfix Increment)
                   4311: @cindex operators, ++
                   4312: 
1.28      snw      4313: Increments a variable by 1.
                   4314: 
1.1       snw      4315: @node -
                   4316: @section - (Subtract)
                   4317: @cindex operators, -
                   4318: 
1.28      snw      4319: Subtracts one number from another.
                   4320: 
1.1       snw      4321: @node -=
                   4322: @section -= (Subtract/Assign)
                   4323: @cindex operators, -=
                   4324: 
1.28      snw      4325: @emph{Syntax}
                   4326: 
                   4327: @example
                   4328: S X=5
                   4329: S X-=3 ; => 2
                   4330: @end example
                   4331: 
                   4332: Decrements the variable on the LHS by the value on the RHS.
                   4333: 
1.1       snw      4334: @node --
                   4335: @section -- (Postfix Decrement)
                   4336: @cindex operators, --
                   4337: 
1.28      snw      4338: Decrements the variable by one.
                   4339: 
1.1       snw      4340: @node *
                   4341: @section * (Multiply)
                   4342: @cindex operators, *
                   4343: 
1.28      snw      4344: Multiplies one number by another.
                   4345: 
1.1       snw      4346: @node *=
                   4347: @section *= (Multiply/Assign)
                   4348: @cindex operators, *=
                   4349: 
1.28      snw      4350: 
                   4351: 
1.1       snw      4352: @node /
                   4353: @section / (Divide)
                   4354: @cindex operators, /
                   4355: 
                   4356: @node /=
                   4357: @section /= (Divide/Assign)
                   4358: @cindex operators, /=
                   4359: 
                   4360: @node \
                   4361: @section \ (Integer Divide)
                   4362: @cindex operators, \
                   4363: 
                   4364: @node \=
                   4365: @section \= (Integer Divide/Assign)
                   4366: @cindex operators, \=
                   4367: 
                   4368: @node #
                   4369: @section # (Modulo)
                   4370: @cindex operators, #
                   4371: 
                   4372: @node #=
                   4373: @section #= (Modulo/Assign)
                   4374: @cindex operators, #=
                   4375: 
                   4376: @node **
                   4377: @section ** (Exponentiate)
                   4378: @cindex operators, **
                   4379: 
                   4380: @node **=
                   4381: @section **= (Exponentiate/Assign)
                   4382: @cindex operators, **=
                   4383: 
                   4384: @node <
                   4385: @section < (Less Than)
                   4386: @cindex operators, <
                   4387: 
                   4388: @node <=
                   4389: @section <= (Less Than or Equal To)
                   4390: @cindex operators, <=
                   4391: 
                   4392: @node >
                   4393: @section > (Greater Than)
                   4394: @cindex operators, >
                   4395: 
                   4396: @node >=
                   4397: @section >= (Greater Than or Equal To)
                   4398: @cindex operators, >=
                   4399: 
                   4400: @node _
                   4401: @section _ (Concatenate)
                   4402: @cindex operators, _
                   4403: 
                   4404: @node _=
                   4405: @section _= (Concatenate/Assign)
                   4406: @cindex operators, _=
                   4407: 
                   4408: @node =
                   4409: @section = (Equals)
                   4410: @cindex operators, =
                   4411: 
                   4412: @node [
                   4413: @section [ (Contains)
                   4414: @cindex operators, [
                   4415: 
                   4416: @node ]
                   4417: @section ] (Follows)
                   4418: @cindex operators, ]
                   4419: 
                   4420: @node ]]
                   4421: @section ]] (Sorts After)
                   4422: @cindex operators, ]]
                   4423: 
                   4424: @node ?
                   4425: @section ? (Pattern Match)
                   4426: @cindex operators, ?
                   4427: 
                   4428: @node &
                   4429: @section & (Logical AND)
                   4430: @cindex operators, &
                   4431: 
                   4432: @node ! (Operator)
                   4433: @section ! (Logical OR)
                   4434: @cindex operators, !
                   4435: 
                   4436: @node '
                   4437: @section ' (Logical NOT)
                   4438: @cindex operators, '
                   4439: 
                   4440: @node @@ (Operator)
                   4441: @section @@ (Indirect)
                   4442: @cindex operators, @@
                   4443: 
                   4444: @node Routines
                   4445: @chapter Routines
                   4446: @cindex routines
                   4447: 
                   4448: A @emph{routine} is a file containing M source code to be processed by FreeM.
                   4449: 
                   4450: Routines exist within a @emph{namespace} (such as @code{SYSTEM} or @code{USER}), which in turn exist within an @emph{environment} (such as @code{DEFAULT}).
                   4451: 
                   4452: @menu
                   4453: * Routine Naming::              Requirements and conventions for routine names.
                   4454: @end menu
                   4455: 
                   4456: 
                   4457: @node Routine Naming
                   4458: @section Routine Naming
                   4459: The routine's filename follows the format @code{NAME.m}, where @code{NAME} is the name of the routine, and @code{.m} is the filename extension.
                   4460: 
                   4461: Routine naming rules are as follows:
                   4462: 
                   4463: @itemize @bullet
                   4464: @item Routine names must begin with an upper- or lower-case letter, or a @code{%} sign
                   4465: @item Within the routine name, you may have upper-case or lower-case letters or digits
                   4466: @item The entire routine name must not be longer than 255 characters
                   4467: @end itemize
                   4468: 
                   4469: Routines whose names begin with @code{%} must be located in the @code{SYSTEM} namespace. Other routines may be located in any namespace.
                   4470: 
                   4471: @node Types
                   4472: @chapter Types
                   4473: @cindex types
                   4474: @cindex data types
                   4475: 
                   4476: FreeM supports all @emph{libdatatype} types defined in the former MDC's @emph{Millennium Draft Standard}, with the exception of @code{MATRIX}, and with extensions supporting object-oriented programming. A notable enhancement in FreeM is that the library data types can be used in the @emph{formallist} of any extrinsic function or subroutine; not only in @emph{libraryelement}s.
                   4477: 
                   4478: @menu
                   4479: * BOOLEAN::                     Truth values.
                   4480: * COMPLEX::                     Numbers with real and imaginary parts.
                   4481: * INTEGER::                     Numbers with no decimal part.
                   4482: * REAL::                        Numbers with a decimal part.
                   4483: * STRING::                      Arbitrary strings of characters.
                   4484: * Custom Types (Classes)::      User-defined, object-oriented types.
                   4485: @end menu
                   4486: 
                   4487: @node BOOLEAN
                   4488: @section BOOLEAN
                   4489: @cindex data types, BOOLEAN
                   4490: @cindex types, BOOLEAN
                   4491: 
                   4492: The @code{BOOLEAN} type represents any M value that can be interpreted as a truth-value.
                   4493: 
                   4494: @node COMPLEX
                   4495: @section COMPLEX
                   4496: @cindex data types, COMPLEX
                   4497: @cindex types, COMPLEX
                   4498: 
                   4499: The @code{COMPLEX} type is a complex number represented as a string in the format @code{@emph{<real-part>}%@emph{<imaginary-part>}}, where @emph{real-part} and @emph{imaginary-part} are both @code{REAL} numbers. See @ref{REAL} for more information.
                   4500: 
                   4501: FreeM will attempt to interpret any @code{COMPLEX} value according to the usual rules for M canonical numbers, i.e., the string @code{sabc123.345%fbd3.1} would be interpreted as a complex number with the real part being @code{123.345} and the imaginary part being @code{3.1}.
                   4502: 
                   4503: @node INTEGER
                   4504: @section INTEGER
                   4505: @cindex data types, INTEGER
                   4506: @cindex types, INTEGER
                   4507: 
                   4508: An @code{INTEGER} is an interpretation of numeric data with any fractional part removed.
                   4509: 
                   4510: @node REAL
                   4511: @section REAL
                   4512: @cindex data types, REAL
                   4513: @cindex types, REAL
                   4514: 
1.29      snw      4515: A @code{REAL} is a numeric interpretation of data including a fractional part.
                   4516: 
1.1       snw      4517: @node STRING
                   4518: @section STRING
                   4519: @cindex data types, STRING
                   4520: @cindex types, STRING
                   4521: 
1.36      snw      4522: The @code{STRING} is the fundamental FreeM data type. Other types are inferred from the context of their usage.
                   4523: 
                   4524: @subsection String Rules
                   4525: 
                   4526: The following rules apply to all FreeM strings:
                   4527: 
                   4528: @itemize
                   4529: @item Must not exceed 255 characters
                   4530: @item Must not contain @code{$C(0)}, @code{$C(201)}, or @code{$C(202)}
                   4531: @end itemize
                   4532: 
                   4533: @subsection String Quoting Rules
                   4534: Strings in FreeM must be surrounded in double quotes:
                   4535: 
                   4536: @example
                   4537: SET MYSTRING="This is a string literal"
                   4538: @end example
                   4539: 
                   4540: If you want to include double quotes inside of a string, simply double them:
                   4541: 
                   4542: @example
                   4543: SET MYSTRING="This is a ""string literal"" with embedded double quotes"
                   4544: @end example
                   4545: 
1.29      snw      4546: 
1.1       snw      4547: @node Custom Types (Classes)
                   4548: @section Custom Types (Classes)
                   4549: @cindex data types, custom
                   4550: @cindex types, custom
                   4551: @cindex classes
                   4552: 
                   4553: See @ref{Classes}.
                   4554: 
                   4555: @node Globals
                   4556: @chapter Globals
                   4557: @cindex globals
                   4558: @cindex variables, global
                   4559: @cindex data
                   4560: 
1.33      snw      4561: @menu
                   4562: * Globals Overview::            Basics of FreeM persistent storage.
                   4563: * Creating Globals::            How to create globals.
                   4564: * Removing Globals::            How to remove globals.
                   4565: * Global Storage::              How globals are stored.
                   4566: @end menu
                   4567: 
                   4568: @node Globals Overview
                   4569: @section Globals Overview
                   4570: 
1.31      snw      4571: FreeM supports typical M globals, which are often described as persistent, hierachical sparse arrays. Globals make it relatively simple to include persistent data in an application without requiring the developer to use an external database management system, and offer syntax and semantics so similar to M local variables and structured system variables that moving from one to the other is seamless.
                   4572: 
                   4573: Each global comprises three elements:
                   4574: 
                   4575: @itemize @bullet
                   4576: @item
                   4577: An alphabetic name beginning with a caret (@code{^}) or a caret and a percent sign (@code{^%})
                   4578: @item
                   4579: Optionally, one or more comma-delimited subscripts, enclosed in parentheses
                   4580: @item
                   4581: A value of up to 255 characters in length
                   4582: @end itemize
                   4583: 
1.36      snw      4584: A leading percent sign in the global name will force the named global into the @code{SYSTEM} namespace of the current FreeM environment.
1.31      snw      4585: 
                   4586: @node Creating Globals
                   4587: @section Creating Globals
                   4588: @cindex globals, creating
                   4589: 
                   4590: To create a global, you can use the @code{SET} command:
                   4591: 
                   4592: @example
                   4593: SET ^MYGLOBAL("foo","bar")="this is the data value"
                   4594: @end example
                   4595: 
                   4596: @node Removing Globals
                   4597: @section Removing Globals
                   4598: @cindex globals, removing
                   4599: 
                   4600: To remove an entire global, you can use the @code{KILL} command with the unsubscripted name of the global:
                   4601: 
                   4602: @example
                   4603: KILL ^MYGLOBAL
                   4604: @end example
                   4605: 
                   4606: If you only want to remove part of a global, i.e., beginning at a certain subscript level, use the @code{KILL} command with a subscripted name:
                   4607: 
                   4608: @example
                   4609: KILL ^MYGLOBAL("foo")
                   4610: @end example
                   4611: 
                   4612: This will remove only the @code{"foo"} subscript and all of its children.
                   4613: 
                   4614: If you only want to remove the data value at a specific subscript level, leaving the subscript itself intact, use @code{KVALUE}:
                   4615: 
                   4616: @example
                   4617: KVALUE ^MYGLOBAL("foo")
                   4618: @end example
                   4619: 
                   4620: @node Global Storage
                   4621: @section Global Storage
                   4622: @cindex globals, storage
                   4623: 
                   4624: FreeM globals are stored in @code{$PREFIX/var/freem/@emph{<environment-name>}/@emph{<namespace-name>}/globals} in a binary format.
                   4625: 
                   4626: Global files have a header of the following format:
                   4627: 
                   4628: @verbatim
                   4629: typedef struct global_header {
                   4630:     
                   4631:     char magic[5]; /* FRMGL */
                   4632:     int format_version;
                   4633:     char host_triplet[40];
                   4634:     char host_id[256];
                   4635:     
                   4636:     unsigned long block_size;
                   4637:     unsigned long last_transaction_id;
                   4638: 
                   4639:     long created;
                   4640:     long last_backup;
                   4641:     
                   4642: } global_header;
                   4643: @end verbatim
                   4644: 
1.1       snw      4645: @node Concurrency Control
                   4646: @chapter Concurrency Control
                   4647: @cindex concurrency control
                   4648: @cindex locking
                   4649: @cindex transaction processing
                   4650: 
1.33      snw      4651: @menu
                   4652: * Concurrency Control Overview::                Basics of concurrency control.
                   4653: * Advisory Locks::                              Coordinating access voluntarily.
                   4654: * Transaction Processing::                      Ensuring logical consistency.
                   4655: @end menu
                   4656: 
                   4657: @node Concurrency Control Overview
                   4658: @section Concurrency Control Overview
                   4659: 
1.34      snw      4660: Multitasking, multi-user FreeM applications must concern themselves with conscientious management of concurrent access to globals in order to maintain logical consistency and prevent concurrent reads and writes from conflicting with each other.
1.31      snw      4661: 
1.34      snw      4662: In FreeM, there are two mechanisms provided for managing concurrent global access: @emph{advisory locks}, and @emph{transaction processing}.
                   4663: 
                   4664: Advisory locks allow applications to voluntarily coordinate concurrent access to globals with the @code{LOCK} command, and require each application to check the @code{LOCK} status prior to accessing a global.
                   4665: 
                   4666: Transaction processing allows applications to delineate sets of global operations (sets, kills, etc.) as being part of a transaction, in which no operations are performed against the globals contained within the transaction until the transaction is committed. In addition, processes other than the one running the transaction will be forced to wait to access globals for either the duration of the commit phase (@emph{batch mode}), or for the entire duration of the transaction (@emph{serial mode}).
1.31      snw      4667: 
1.33      snw      4668: @node Advisory Locks
                   4669: @section Advisory Locks
                   4670: 
1.31      snw      4671: @node Transaction Processing
                   4672: @section Transaction Processing
                   4673: @cindex transaction processing
                   4674: 
                   4675: FreeM implements a significant subset of the transaction processing features from @emph{ANSI X11.1-1995}. This allows a series of global operations to be conducted all at once, either in batch mode (where concurrency is not disturbed), or in serial mode (where writes are guaranteed to be atomic, consistent, isolated, and durable).
                   4676: 
                   4677: @subsection Theory of Operation
                   4678: 
                   4679: FreeM uses a pessimistic concurrency control mechanism for @code{SERIAL} transactions, meaning that any @code{TSTART} command that includes the @code{SERIAL} transaction parameter will cause the process to acquire the transaction processing mutex, which prevents any process but the one holding the mutex from performing any data access (read or write) until either @code{TCOMMIT} or @code{TROLLBACK} is called, either committing or rolling back the transaction, respectively.
                   4680: 
                   4681: Any transaction in between its @code{TSTART} and @code{TCOMMIT}/@code{TROLLBACK} is said to be @emph{in-flight}. During the in-flight stage, pending global operations are held only in memory and after-image journals.
                   4682: 
                   4683: FreeM maintains a list of all globals affected during a transaction in-flight. When a @code{TCOMMIT} is reached, FreeM will generate a @emph{checkpoint} of each global data file to be changed by the transaction. These checkpoints allow all FreeM globals to be restored to their pre-transaction state if a @code{TCOMMIT} should fail part of the way through its operation. 
                   4684: 
                   4685: Checkpoints can have one of two modes:
                   4686: 
                   4687: @table @asis
                   4688: 
                   4689: @item @code{CP_REMOVE}
                   4690: Used for globals that did not exist prior to the beginning of this transaction. Simply marks the entire global data file for deletion in case of @code{TCOMMIT} failure.
                   4691: 
                   4692: @item @code{CP_RESTORE}
                   4693: Used for globals that @emph{did} exist prior to the beginning of this transaction. In this case, the entire global data file is copied to a new file with a @code{.chk} extension. In cases of @code{TCOMMIT} failure, @code{CP_RESTORE} checkpoint files will be restored over the partially-modified live data file.
                   4694: 
                   4695: @end table
                   4696: 
                   4697: The below example shows a few global operations and checkpoints for a transaction in-flight using the @code{trantab} direct-mode command:
                   4698: 
                   4699: @verbatim
                   4700: TL1:DEFAULT.USER> trantab
                   4701:  $TLEVEL 1*
                   4702:   Operations for Transaction ID: 6ea14aad-b8f1-47f9-9f52-4f513f892bc0 [RESTARTABLE SERIAL]
                   4703: 
                   4704:    OP. NO.   ACTION         KEY/DATA
                   4705:    -------   ------         --------
                   4706:    1         SET            ^FOO=3
                   4707:    2         KILL           ^FOO
                   4708:    3         SET            ^snw=10
                   4709:    4         SET            ^BRANDNEW=6
                   4710: 
                   4711:   Global checkpoints:
                   4712: 
                   4713:    GLOBAL                        MODE                FILES
                   4714:    ------                        ----                -----
                   4715:    ^BRANDNEW                     CP_REMOVE           IN:   /usr/local/var/freem/USER/globals/^BRANDNEW
                   4716:    ^snw                          CP_RESTORE          IN:   /usr/local/var/freem/USER/globals/^snw
                   4717:                                                      OUT:  /usr/local/var/freem/USER/globals/^snw.23390.1.chk
                   4718:    ^FOO                          CP_RESTORE          IN:   /usr/local/var/freem/USER/globals/^FOO
                   4719:                                                      OUT:  /usr/local/var/freem/USER/globals/^FOO.23390.1.chk
                   4720: @end verbatim
                   4721: 
                   4722: In the above example, @code{IN} files are the live data file that will be overwritten or removed, and @code{OUT} files are the checkpoints themselves. Note that @code{OUT} files are only used for @code{CP_RESTORE} checkpoints.
                   4723: 
                   4724: @subsection Using Transaction Processing
                   4725: 
                   4726: To use transactions in FreeM, you need to be familiar with three commands:
                   4727: 
                   4728: @itemize @bullet
                   4729: @item
                   4730: @code{TSTART}
                   4731: @item
                   4732: @code{TCOMMIT}
                   4733: @item
                   4734: @code{TROLLBACK}
                   4735: @end itemize
                   4736: 
                   4737: With transaction processing, global variable operations occurring between @code{TSTART} and @code{TCOMMIT} commands will be contained within the transaction.
                   4738: 
                   4739: The atomicity, consistency, isolation, and durability facets of FreeM transaction hinge on the transaction mode.
                   4740: 
                   4741: @subsubsection BATCH Transactions
                   4742: @code{BATCH} transactions offer higher performance, and allow other applications aside from the one doing the transaction to continue normal operations until the transaction is committed with @code{TCOMMIT}. In batch mode, other processes are only locked out of normal operation during the commit phase of the transaction.
                   4743: 
                   4744: The effect of this is that the operations within the batch transaction will not be interleaved with global writes from other applications, but the entire lifetime of the transaction is not guaranteed to be serialized with respect to the transaction processing activities of other running applications in the environment.
                   4745: 
                   4746: @subsubsection SERIAL Transactions
                   4747: @code{SERIAL} transactions offer full ACID compliance at the expense of multiprocessing performance. In serial mode, a @code{TSTART} blocks all activity from all other FreeM processes in the environment, and this blocking effect is not released until the transaction is committed with @code{TCOMMIT} or rolled back with @code{TROLLBACK} (or due to abnormal conditions in the environment that preclude the successful completion of the transaction).
                   4748: 
1.1       snw      4749: @node Local Variables
                   4750: @chapter Local Variables
                   4751: @cindex variables, local
                   4752: @cindex local variables
                   4753: 
                   4754: @node Scoping
                   4755: @chapter Scoping
                   4756: @cindex scoping
                   4757: 
                   4758: @node Decision Constructs
                   4759: @chapter Decision Constructs
                   4760: @cindex decision constructs
                   4761: @cindex IF
                   4762: @cindex ELSE
                   4763: @cindex THEN
                   4764: @cindex postconditionals
                   4765: 
                   4766: @node Branch Constructs
                   4767: @chapter Branch Constructs
                   4768: @cindex branch constructs
                   4769: @cindex DO
                   4770: @cindex GOTO
                   4771: @cindex JOB
                   4772: 
                   4773: @node Loop Constructs
                   4774: @chapter Loop Constructs
                   4775: @cindex loop constructs
                   4776: @cindex FOR
                   4777: 
                   4778: @node Modular Programming
                   4779: @chapter Modular Programming
                   4780: @cindex modular programming
                   4781: @cindex functions, extrinsic
                   4782: @cindex subroutines
                   4783: 
1.2       snw      4784: @menu
                   4785: * Subroutines::         Making sections of code reusable.
                   4786: * Extrinsic Functions:: Reusable code that returns a value.
                   4787: @end menu
                   4788: 
1.1       snw      4789: @node Subroutines
                   4790: @section Subroutines
                   4791: 
                   4792: @node Extrinsic Functions
                   4793: @section Extrinsic Functions
                   4794: 
                   4795: @node Object-Oriented Programming
                   4796: @chapter Object-Oriented Programming
                   4797: @cindex object-oriented programming
                   4798: @cindex programming, object-oriented
                   4799: 
1.2       snw      4800: @menu
1.29      snw      4801: * Classes::                         The basis of object-oriented programming.
                   4802: * Inheritance::                     Basing one class upon another.
                   4803: * Methods::                         Attaching code to a class.
                   4804: * Public and Private Variables::    Managing class member access.
1.31      snw      4805: * Instantiating Objects::           Creating instances of classes.
                   4806: * Determining Object Class::        Getting object information at runtime.
1.2       snw      4807: @end menu
                   4808: 
1.1       snw      4809: @node Classes
                   4810: @section Classes
                   4811: 
1.33      snw      4812: @menu
                   4813: * Class Overview::                  Class basics.
                   4814: * Constructors::                    Managing object creation.
                   4815: * Destructors::                     Cleaning up.
                   4816: * Runtime Polymorphism::            Selecting methods at runtime.
                   4817: @end menu
                   4818: 
                   4819: @node Class Overview
                   4820: @subsection Class Overview
                   4821: 
1.29      snw      4822: A @emph{class} is the primary organizing concept of FreeM support for object-oriented programming, and in FreeM, is simply an M routine with a few special properties:
                   4823: 
                   4824: @example
                   4825: MYCLASS(THIS,INIT):OBJECT ; Constructor for MYCLASS, inherits OBJECT
                   4826:   ; two private variables
                   4827:   S THIS("NUMERATOR"):PRIVATE=$P(INIT,"/",1)
                   4828:   S THIS("DENOMINATOR"):PRIVATE=$P(INIT,"/",2)
                   4829:   Q
                   4830:   ;
                   4831: DESTROY(THIS) ; This is the destructor
                   4832:   Q
                   4833: @end example
                   4834: 
                   4835: The above example demonstrates general class syntax.
                   4836: 
                   4837: @node Constructors
                   4838: @subsection Constructors
                   4839: 
                   4840: A @emph{constructor} is an M entry point that is called when a new instance of a class is created.
                   4841: 
                   4842: A constructor must be the first entry point in a class routine, its tag must match the class/routine name, and it must take two arguments, @code{THIS} and @code{INIT}.
                   4843: 
                   4844: @code{THIS} represents the instance of the object being accessed, and @code{INIT} represents an initializer that can be used to assign an initial value to the object when instantiating the class.
                   4845: 
                   4846: A constructor looks like this:
                   4847: 
                   4848: @example
                   4849: %FRACTION(THIS,INIT):OBJECT ;
                   4850:    S THIS("NUMERATOR"):PRIVATE=$P(INIT,"/",1)
                   4851:    S THIS("DENOMINATOR"):PRIVATE=$P(INIT,"/",2)
                   4852:    Q
                   4853: @end example
                   4854: 
                   4855: @emph{Syntax}
                   4856: @example
                   4857: @emph{<class-name>}(THIS,INIT)[:@emph{<superclass>}]
                   4858: @end example
                   4859: 
                   4860: In the above example, @emph{<superclass>} represents the name of a class from which this class should inherit. In this case, the @code{FRACTION} class inherits from the @code{OBJECT} class. Note that this is not strictly necessary in this case, as all classes in FreeM automatically inherit from @code{OBJECT}.
                   4861: 
                   4862: @node Destructors
                   4863: @subsection Destructors
                   4864: A @code{destructor} is called when you @code{KILL} an instance variable. Its tag must be @code{DESTROY}, and it must take one argument (@code{THIS}).
                   4865: 
                   4866: The destructor should be used to clean up any resources used by class methods.
                   4867: 
                   4868: A destructor looks like this:
                   4869: 
                   4870: @example
                   4871: DESTROY(THIS) ;
                   4872:   ; free any resources that should be freed at the end of the object's lifetime
                   4873:   Q
                   4874: @end example
1.2       snw      4875: 
1.1       snw      4876: @node Inheritance
1.29      snw      4877: @section Inheritance
                   4878: 
                   4879: Every class you create will automatically inherit the methods and functionality of the @code{OBJECT} class, supplied with FreeM.
                   4880: 
                   4881: When attempting to call a method, FreeM will first search the class routine for a matching entry point, and then follow the inheritance chain upwards until a matching entry point is found. If the final class in the chain does not have a matching entry point, FreeM will try to find a matching entry point in the @code{OBJECT} class.
                   4882: 
                   4883: Inheritance is achieved by specifying the name of the superclass in the constructor:
                   4884: 
                   4885: @example
                   4886: CLASS(THIS,INIT):SUPERCLASS
                   4887: @end example
                   4888: 
                   4889: @node Runtime Polymorphism
                   4890: @subsection Runtime Polymorphism
                   4891: 
                   4892: You can achieve runtime polymorphism by subclassing, and defining methods in the subclass that match the names of existing methods in the superclass. Following FreeM inheritance rules, the overridden method in the subclass will be called, and the method in the superclass will not.
                   4893: 
                   4894: Note that the overridden method in the subclass can take a different set or number of arguments than the @emph{formallist} of the superclass method would specify.
1.1       snw      4895: 
                   4896: @node Methods
1.29      snw      4897: @section Methods
                   4898: Class methods are defined as tags with @emph{formallist}s in a class routine, and per the typical FreeM object pattern, must take at least one argument, being @code{THIS} (representing a reference to the object instance being accessed).
1.1       snw      4899: 
1.29      snw      4900: The following class (@code{MYCLASS}) has a constructor, a destructor, and a method called @code{MYMETHOD}:
                   4901: 
                   4902: @example
                   4903: %MYCLASS(THIS,INIT) ;
                   4904:   Q THIS
                   4905: DESTROY(THIS) ;
                   4906:   Q
                   4907: MYMETHOD(THIS) ;
                   4908:   Q "VALUE"
                   4909: @end example
                   4910: 
1.31      snw      4911: The dot operator is used to invoke class methods:
                   4912: 
                   4913: @example
                   4914: DEFAULT.USER> N MYOBJ=$#^%MYCLASS("")
                   4915: DEFAULT.USER> W MYOBJ.MYMETHOD()
                   4916: VALUE
                   4917: @end example
                   4918: 
1.29      snw      4919: @node Public and Private Variables 
                   4920: @section Public and Private Variables
                   4921: 
1.30      snw      4922: FreeM supports private fields with the @code{:PRIVATE} specifier in the @code{SET} command, enforcing classical object-oriented data encapsulation. The @code{:PUBLIC} specifier is provided for completeness, and is the default.
1.29      snw      4923: 
                   4924: The below constructor for a @code{FRACTION} class defines two private fields:
                   4925: 
                   4926: @example
                   4927: %FRACTION(THIS,INIT):OBJECT ;
                   4928:    S THIS("NUMERATOR"):PRIVATE=$P(INIT,"/",1)
                   4929:    S THIS("DENOMINATOR"):PRIVATE=$P(INIT,"/",2)
                   4930:    Q
                   4931: @end example   
                   4932: 
                   4933: Either of the following commands will create a public field:
                   4934: 
                   4935: @example
                   4936:   S THIS("VARNAM")="Initial Value"
                   4937:   S THIS("VARNAM"):PUBLIC="Initial Value"
                   4938: @end example
1.1       snw      4939: 
1.29      snw      4940: Attempting to access private fields from outside of the class will raise error condition @code{ZOBJFLDACCV}. 
1.1       snw      4941: 
1.31      snw      4942: @node Instantiating Objects
                   4943: @section Instantiating Objects
                   4944: 
                   4945: To instantiate an object (i.e., create an object from a certain class), you will use the @code{NEW} command as follows:
                   4946: 
                   4947: @example
                   4948: NEW MYSTR=$#^%STRING("myString")
                   4949: @end example
                   4950: 
                   4951: This will create a local variable called MYSTR of type STRING, and initialize it with the value myString. 
                   4952: 
                   4953: @node Determining Object Class
                   4954: @section Determining Object Class
                   4955: 
                   4956: To determine the class of any FreeM local variable, you will use the @code{$$TYPE()} method:
                   4957: 
                   4958: @example
                   4959: USER> W MYSTR.$$TYPE()
                   4960: ^%STRING
                   4961: @end example
                   4962: 
                   4963: The @code{$$TYPE()} method is a member of the @code{OBJECT} class. 
                   4964: 
1.1       snw      4965: @node Libraries
                   4966: @chapter Libraries
                   4967: @cindex libraries
                   4968: 
                   4969: @node Sequential I/O
                   4970: @chapter Sequential I/O
                   4971: 
                   4972: @node Network I/O
                   4973: @chapter Network I/O
                   4974: @cindex networks, input and output
                   4975: 
                   4976: Network I/O in FreeM is supplied through I/O channels 100-255. The normal @code{READ} and @code{WRITE} syntax will work with network sockets, with a few exceptions.
                   4977: 
                   4978: @section Opening and Connecting a Client Socket
                   4979: @cindex networks, opening and connecting client sockets
                   4980: 
                   4981: To open a client socket and connect to it, you will need to call the @code{OPEN} command and the @code{USE} command:
                   4982: 
                   4983: @example
                   4984:   ;
                   4985:   ; Set socket read terminator to LF
                   4986:   ;
                   4987:   SET ^$DEVICE(100,"OPTIONS","TERMINATOR")=$C(10)
                   4988:   ;
                   4989:   ; Open an IPv4 TCP socket to mail.mydomain.com on port 25 (SMTP)
                   4990:   ; and connect to it
                   4991:   ;
                   4992:   OPEN 100:"mail.mydomain.com:25:IPV4:TCP"
                   4993:   USE 100:/CONNECT
                   4994:   ;
                   4995:   ; Read a line of input from the remote host and write it to the terminal
                   4996:   ;
                   4997:   NEW LINE
                   4998:   READ LINE
                   4999:   USE 0
                   5000:   WRITE LINE,!
                   5001:   ;
                   5002:   ; CLOSE the socket and disconnect
                   5003:   ;
                   5004:   CLOSE 100
                   5005:   QUIT
                   5006: @end example
                   5007: 
                   5008: @node Extended Global References
                   5009: @chapter Extended Global References
                   5010: @cindex global references, extended
                   5011: @cindex extended global references
                   5012: 
                   5013: @section Standard Extended Global References
                   5014: @cindex extended global references, standard
                   5015: 
                   5016: FreeM supports extended global references, allowing the user to access globals in namespaces other than the current default namespace and the @code{SYSTEM} namespace, without switching to the other namespace.
                   5017: 
                   5018: For example, if you are in the @code{USER} namespace, the following code will print the value of @code{^VA(200,0)} in the @code{VISTA} namespace:
                   5019: 
                   5020: @example
                   5021:   WRITE ^|"VISTA"|VA(200,0),!
                   5022: @end example
                   5023: 
                   5024: You may also use an expression that resolves to a string containing a valid namespace name:
                   5025: 
                   5026: @example
                   5027:   SET NS="VISTA"
                   5028:   WRITE ^|NS|VA(200,0),!
                   5029: @end example  
                   5030: 
                   5031: @node Global Aliasing
                   5032: @chapter Global Aliasing
                   5033: @cindex aliasing, global
                   5034: @cindex globals, aliasing
                   5035: 
                   5036: FreeM provides the ability to set alternative names for M global variables.
                   5037: 
                   5038: To create an alias of @code{^FOO} named @code{^BAR}, use the following command:
                   5039: 
                   5040: @example
                   5041:   SET ^$JOB($JOB,"ALIASES","^BAR")="^FOO"
                   5042: @end example
                   5043: 
                   5044: If such an alias is set, any reference to global variable @code{^BAR} will affect @code{^FOO} instead of @code{^BAR} until @code{^$JOB($JOB,"ALIASES","^BAR")} is @code{KILL}ed. If @code{^BAR} existed prior to the definition of this alias, its data will be unavailable to and unaffected by application code.  
                   5045: 
                   5046: @node Global Mappings
                   5047: @chapter Global Mappings
                   5048: @cindex mappings, global
                   5049: @cindex globals, mapping
                   5050: 
                   5051: FreeM supports creating persistent mappings through which arbitrary global names may be mapped to specific namespaces. This allows non-@code{%} globals to be stored in the @code{SYSTEM} namespace, or @code{%} globals to be stored in non-@code{SYSTEM} namespaces.
                   5052: 
                   5053: To map the @code{^FOO} global to the @code{SYSTEM} namespace, any of the following will work:
                   5054: 
                   5055: @example
                   5056:   MAP GLOBAL ^FOO="SYSTEM"
                   5057:   SET ^$GLOBAL("FOO","NAMESPACE")="SYSTEM"
                   5058:   SET ^$SYSTEM("MAPPINGS","GLOBAL","^FOO")="SYSTEM"
                   5059: @end example
                   5060: 
                   5061: There is no functional difference in any of the three approaches; the method you choose is a matter of personal preference.
                   5062: 
                   5063: To remove the above mapping, any of the following examples will also work:
                   5064: 
                   5065: @example
                   5066:   UNMAP GLOBAL ^FOO
                   5067:   KILL ^$GLOBAL("FOO","NAMESPACE")
                   5068:   KILL ^$SYSTEM("MAPPINGS","GLOBAL","^FOO")
                   5069: @end example
                   5070: 
                   5071: 
                   5072: 
                   5073: @node Asynchronous Event Handling
                   5074: @chapter Asynchronous Event Handling
                   5075: @cindex event handling, asynchronous
                   5076: 
                   5077: Asynchronous event handling in FreeM follows the specifications of the unpublished MDC @emph{Millennium Draft Standard}.
                   5078: 
                   5079: @section Setting Up Async Event Handlers
                   5080: 
                   5081: Asynchronous event handlers are configured through the @code{^$JOB} structured system variable for job-specific events, and the @code{^$SYSTEM} structured system variable for system-wide events. In order to become proficient in writing asynchronous event handling code, you need to be aware of several important concepts:
                   5082: 
                   5083: @table @emph
                   5084: 
                   5085: @item Event Classes
                   5086: @emph{Event classes} denote particular categories of events. These include @code{COMM}, @code{HALT}, @code{IPC}, @code{INTERRUPT}, @code{POWER}, @code{TIMER}, @code{TRIGGER}, and @code{USER} event classes. At present, only @code{INTERRUPT} and @code{TRIGGER} event classes are supported.
                   5087: 
                   5088: @item Event Identifiers
                   5089: @emph{Event identifiers} denote the precise nature of the event that has occurred. For instance, resizing the terminal window in which a FreeM job is running will send an event of class @code{INTERRUPT} with an event identifier of @code{SIGWINCH} (short for @emph{SIGnal WINdow CHange}).
                   5090: 
                   5091: @item Event Handlers
                   5092: @emph{Event handlers} are M routines or subroutines that can be registered to run when an event of a certain event class occurs.
                   5093: 
                   5094: @item Event Registration
                   5095: @emph{Event registration} is the process of modifying the @code{^$JOB} or @code{^$SYSTEM} SSVN to associate a particular event class and event identifier with an event handler routine or subroutine.
                   5096: 
                   5097: @item Event Blocking and Unblocking
                   5098: @emph{Event blocking} is the means by which asynchronous event handling can be temporarily suspended. For example, asynchronous events are temporarily and implicitly blocked for the duration of event handler execution, unless explicitly un-blocked within the event handler. Event handling can also be blocked and unblocked programatically from M code using the @code{ABLOCK} and @code{AUNBLOCK} commands.
                   5099: 
                   5100: @end table
                   5101: 
                   5102: The following sections of this chapter will take you step-by-step through setting up an event handler for @code{SIGWINCH} signal handling.
                   5103: 
                   5104: @section Registering an Asynchronous Event Handler
                   5105: @cindex event handlers, registration
                   5106: 
                   5107: To register a job-specific event handler that will only execute in the current FreeM process, use the following syntax:
                   5108: 
                   5109: @example
                   5110:   SET ^$JOB($JOB,"EVENT",@emph{event-class},@emph{event-identifier})=@emph{entryref}
                   5111: @end example
                   5112: 
                   5113: To register a system-wide event handler that will execute in every FreeM process, use the following syntax:
                   5114: 
                   5115: @example
                   5116:   SET ^$SYSTEM("EVENT",@emph{event-class},@emph{event-identifier})=@emph{entryref}
                   5117: @end example
                   5118: 
                   5119: For example, use the following to register @code{^RESIZE} as an asynchronous event handler for @code{SIGWINCH} events:
                   5120: 
                   5121: @example
                   5122:   SET ^$JOB($JOB,"EVENT","INTERRUPT","SIGWINCH")="^RESIZE"
                   5123: @end example
                   5124: 
                   5125: This by itself will not enable asynchronous event handling, as it merely @emph{registers} an event handler, associating it with event class @code{INTERRUPT} and event identifier @code{SIGWINCH}.
                   5126: 
                   5127: @section Enabling Asynchronous Event Handling
                   5128: @cindex event handlers, enabling
                   5129: 
                   5130: In order to enable asyncronous event handling, the @code{ASTART} command is used. In the following example, we will enable asynchronous event handling for the @code{INTERRUPT} event class:
                   5131: 
                   5132: @example
                   5133:   ASTART "INTERRUPT"
                   5134: @end example
                   5135: 
                   5136: Omitting the @code{"INTERRUPT"} argument will enable asynchronous event handling for @emph{all} event classes. See @code{ASTART} in the commands section for more details.
                   5137: 
                   5138: Once this is done, any event handlers registered for the @code{INTERRUPT} event class in @code{^$JOB} will be executed asynchronously as appropriate.
                   5139: 
                   5140: Please note that @code{ASTART "TRIGGER"} is run implicitly at FreeM startup, to ensure consistency in applications depending on business logic contained in system-wide global triggers. To disable this behavior, add @code{ASTOP "TRIGGER"} to the @code{LOCAL.STARTUP} routine in the @code{USER} namespace. If @code{LOCAL.STARTUP} does not yet exist in your environment, you may create it by typing @code{fmadm edit routine USER LOCAL.STARTUP} from your UNIX command-line shell.
                   5141: 
                   5142: @section Disabling Asynchronous Event Handling
                   5143: @cindex event handlers, disabling
                   5144: 
                   5145: To disable asynchronous event handling, the @code{ASTOP} command is used. In the following example, we will disable asynchronous event handling for the @code{INTERRUPT} event class:
                   5146: 
                   5147: @example
                   5148:   ASTOP "INTERRUPT"
                   5149: @end example
                   5150: 
                   5151: Omitting the @code{"INTERRUPT"} argument will disable asynchronous event handling for @emph{all} event classes. See @code{ASTOP} in the commands section for more details.
                   5152: 
                   5153: You may also disable asynchronous event handling for a specific event identifier by @code{KILL}ing the appropriate node in the @code{^$JOB} SSVN, which unregisters the event handler altogether. The following example will unregister the event handler for the @code{SIGWINCH} event identifier:
                   5154: 
                   5155: @example
                   5156:   KILL ^$JOB($JOB,"EVENT","INTERRUPT","SIGWINCH")
                   5157: @end example  
                   5158: 
                   5159: @section Temporarily Blocking Asynchronous Event Handling
                   5160: @cindex event handlers, blocking
                   5161: 
                   5162: To temporarily block processing of specific event classes, you will use the @code{ABLOCK} command. @code{ABLOCK} functions incrementally, that is, each successive call to @code{ABLOCK} will increment a counter of blocks held for the specified event class or classes, and each successive call to @code{AUNBLOCK} will decrement that counter. Event handling for the specified event classes will be blocked as long as the @code{ABLOCK} counter for those classes is greater than zero. Thus, event blocking is cumulative, in a manner similar to M incremental locks.
                   5163: 
                   5164: The following example blocks asynchronous event handling for the @code{INTERRUPT} event class:
                   5165: 
                   5166: @example
                   5167:   ABLOCK "INTERRUPT"
                   5168: @end example
                   5169: 
                   5170: Note that entering an event handler causes an implicit @code{ABLOCK} of @emph{all} event classes, to prevent event handlers from interrupting other event handlers during their execution. This may be overridden by calling @code{AUNBLOCK} for one or more event classes within an event handler. However, unblocking event handling during an event handler should be done with great caution, as this can make the flow of code execution somewhat unpredictable, especially if M globals are modified inside of an event handler routine or subroutine.
                   5171: 
                   5172: Modifying M globals within event handlers is allowed but strongly discouraged, as doing so can lead to logical corruption of the data. If you must modify an M global within an event handler, guard all such operations with prodigious and careful use of @code{LOCK}s, ensuring that such modifications occur in the desired logical order.
                   5173: 
                   5174: @node Global Triggers
                   5175: @chapter Global Triggers
                   5176: @cindex global triggers
                   5177: @cindex triggers
                   5178: 
                   5179: Global triggers use the FreeM asynchronous event handling subsystem to allow a FreeM process to execute arbitrary M code when a particular action occurs on a particular global.
                   5180: 
                   5181: To set up a global trigger, you must set up an event handler for event class @code{TRIGGER}. The event identifier must be in the format of @code{"<action>:<gvn>"}, where @emph{<gvn>} is a global variable name, and @emph{<action>} is one of the following:
                   5182: 
                   5183: @table @asis
                   5184: 
                   5185: @item @code{DATA}
                   5186: Trigger will fire when the @code{$DATA} intrinsic function is called on @emph{<gvn>}.
                   5187: 
                   5188: @item @code{GET}
                   5189: Trigger will fire when @emph{<gvn>} is read from.
                   5190: 
                   5191: @item @code{INCREMENT}
                   5192: Trigger will fire when intrinsic function @code{$INCREMENT} is called on @emph{<gvn>}.
                   5193: 
                   5194: @item @code{KILL}
                   5195: Trigger will fire when @emph{<gvn>} is @code{KILL}ed.
                   5196: 
                   5197: @item @code{NEXT}
                   5198: Trigger will fire when intrinsic function @code{$NEXT} is called on @emph{<gvn>}.
                   5199: 
                   5200: @item @code{ORDER}
                   5201: Trigger will fire when intrinsic function @code{$ORDER} is called on @emph{<gvn>}.
                   5202: 
                   5203: @item @code{QUERY}
                   5204: Trigger will fire when intrinsic function @code{$QUERY} is called on @emph{<gvn>}.
                   5205: 
                   5206: @item @code{SET}
                   5207: Trigger will fire when @code{SET @emph{<gvn>}=@emph{value}} occurs.
                   5208: 
                   5209: @item @code{ZDATA}
                   5210: Trigger will fire when intrinsic function @code{ZDATA} is called on @emph{<gvn>}.
                   5211: 
                   5212: @end table
                   5213: 
                   5214: When a @code{TRIGGER} event occurs, the @code{"GLOBAL"} node of the @code{^$EVENT} structured system variable will be populated with the global reference that invoked the trigger event.
                   5215: 
                   5216: If a @code{SET} or @code{KILL} trigger was the source of the @code{TRIGGER} event, the @code{OLD_VALUE} node of @code{^$EVENT} will be populated with original value of @code{^$EVENT("GLOBAL")} prior to the change, and @code{NEW_VALUE} will be populated with the new value. This allows triggers to contain logic to undo global changes. This functionality can also be used to provide auditing of specific global changes.
                   5217: 
                   5218: The following example shows a trigger implemented for @code{SET} operations on the @code{^DD} global.
                   5219: 
                   5220: @example
                   5221: TRIGGER ;
                   5222:     ;
                   5223:     ; Set up a SET trigger on ^DD
                   5224:     ;
                   5225:     SET ^$JOB($JOB,"EVENT","TRIGGER","SET:^DD")="ONSET^TRIGGER"
                   5226:     ;
                   5227:     ; Enable the TRIGGER event class
                   5228:     ;
                   5229:     ASTART "TRIGGER"
                   5230:     ;
                   5231:     ; Try setting a node in ^DD
                   5232:     ;
                   5233:     SET ^DD(1)="Test"
                   5234:     ;
                   5235:     ; Quit
                   5236:     ;
                   5237:     QUIT
                   5238:     ;
                   5239:     ;
                   5240: ONSET ;
                   5241:     WRITE "The "_^$EVENT("GLOBAL")_" global node was SET.",!
                   5242:     QUIT
                   5243: @end example
                   5244: 
                   5245: You can also set up a trigger that applies to all FreeM processes by setting descendant subscripts of @code{^$SYSTEM("EVENT","TRIGGER",...)} instead of using @code{^$JOB($JOB,"EVENT","TRIGGER",...)}.
                   5246: 
                   5247: @node Synchronous Event Handling
                   5248: @chapter Synchronous Event Handling
                   5249: 
                   5250: @node GUI Programming with MWAPI
                   5251: @chapter GUI Programming with MWAPI
                   5252: 
                   5253: @node User-Defined Z Commands
                   5254: @chapter User-Defined Z Commands
                   5255: 
                   5256: @node User-Defined Z Functions
                   5257: @chapter User-Defined Z Functions
                   5258: 
                   5259: @cindex z functions, user-defined
                   5260: 
                   5261: @node User-Defined SSVNs
                   5262: @chapter User-Defined SSVNs 
                   5263: 
                   5264: @cindex structured system variables, user-defined
                   5265: @cindex structured system variables
                   5266: 
                   5267: @node Language Dialects
                   5268: @chapter Language Dialects
                   5269: 
                   5270: @cindex language dialects
                   5271: @cindex dialects, language
                   5272: 
                   5273: 
                   5274: @node System Library Routines
                   5275: @chapter System Library Routines
                   5276: @cindex system library routines
                   5277: 
                   5278: @section ^%ZCOLUMNS
                   5279: @cindex ^%ZCOLUMNS
                   5280: @cindex system library routines, ^%ZCOLUMNS
                   5281: 
                   5282: This routine is the implementation of the @code{$ZCOLUMNS} intrinsic special variable.
                   5283: 
1.28      snw      5284: @section %SYSINIT
                   5285: @cindex %SYSINIT
                   5286: @cindex system library routines, %SYSINIT
1.1       snw      5287: 
                   5288: This routine is the default startup routine for FreeM running in direct mode.
                   5289: 
                   5290: Running @code{DO INFO} from direct mode will use this routine to display information about the current FreeM status and namespace configuration.
                   5291: 
                   5292: @section ^%ZHELP
                   5293: @cindex ^%ZHELP
                   5294: @cindex system library routines, ^%ZHELP
                   5295: 
                   5296: This routine implements the online help feature of FreeM, invoked by typing @code{?} in direct mode. It simply asks the underlying system to execute the command @command{info freem}.
                   5297: 
                   5298: @section ^%ZROWS
                   5299: @cindex ^%ZROWS
                   5300: @cindex system library routines, ^%ZROWS
                   5301: 
                   5302: This routine is the implementation of the @code{$ZROWS} intrinsic special variable.
                   5303: 
                   5304: @node Interrupt Handling
                   5305: @chapter Interrupt Handling
                   5306: @cindex interrupt handling
                   5307: 
1.22      snw      5308: When FreeM receives the @code{SIGINT} signal, either by pressing @code{Ctrl-C} during program execution, or by external signal from the operating system, the FreeM environment daemon, or another external process, one of two things can happen, depending on the state of the @code{$ZI} special variable:
1.1       snw      5309: 
                   5310: @table @asis
                   5311: @item @code{$ZI} evaluates @emph{true}
                   5312: In this case, the @code{ZINRPT} error is raised, and normal error handling procedures apply. If neither @code{$ZTRAP} nor @code{$ETRAP} are set, FreeM prints an error diagnostic on the home device and will exit the FreeM process in application mode (i.e., the @code{freem} executable was started with the @code{--routine} or @code{-r} flag), or return to the direct mode prompt otherwise.
                   5313: 
                   5314: This is the default behavior of FreeM.
                   5315: @item @code{$ZI} evaluates @emph{false}
                   5316: In this case, no error is raised, but the @code{$ZCONTROLC} flag is set. In this mode of operation, it is up to program code to check for @code{$ZCONTROLC} and take appropriate action.
                   5317: 
                   5318: Checking the value of @code{$ZCONTROLC} will reset it to @emph{false}.
                   5319: @end table
                   5320: 
                   5321: In either case, if asynchronous event handling is enabled for the @code{INTERRUPT} event class (i.e., @code{ASTART "INTERRUPT"} or @code{ASTART} have been invoked by the current process), an asynchronous event of event class @code{INTERRUPT} and event identifier @code{SIGINT} will be enqueued. 
                   5322: 
                   5323: @node Error Processing
                   5324: @chapter Error Processing
                   5325: @cindex error processing
                   5326: 
                   5327: FreeM exposes three means of processing M program execution errors:
                   5328: 
                   5329: @table @emph
                   5330: 
                   5331: @item FreeM-style error processing
                   5332: FreeM-style error processing exposes a read/write error trap in @code{$ZTRAP}. The contents of @code{$ZTRAP} must be either empty or a valid M entryref, to which FreeM will @code{GOTO} if an error occurs. Each program stack execution level can have its own @code{$ZTRAP} error handler enabled.
                   5333: 
                   5334: @item DSM 2.0-style error processing
                   5335: DSM 2.0-style error processing emulates the @code{$ZTRAP} behavior of Digital Standard MUMPS v2. It has the same behavior as FreeM-style error handling, with the exception that in DSM 2.0-style error processing, only one @code{$ZTRAP} error handler is set across all program stack execution levels.
                   5336: 
                   5337: @item Standard error processing
                   5338: Standard error processing uses the @code{NEW}-able @code{$ETRAP} variable to store error handler code, which may be any valid M code. The code in @code{$ETRAP} will run when an error occurs or the @code{$ECODE} ISV becomes non-empty. Stack information for standard error handling is provided by the @code{$STACK} ISV, the @code{$STACK()} intrinsic pseudo-function, and the @code{NEW}-able @code{$ESTACK} ISV.
                   5339: 
                   5340: If @code{$ETRAP} is non-empty when an error condition occurs, @code{$ZTRAP} is ignored, regardless of whether FreeM-style or DSM 2.0-style error processing is enabled at the time of the error.
                   5341: 
                   5342: @end table
                   5343: 
                   5344: For further information on switching between FreeM-style and DSM 2.0-style @code{$ZTRAP} error handling, see the documentation for the @code{BREAK} command.
                   5345: 
                   5346: @node FreeM Error Codes
                   5347: @chapter FreeM Error Codes
                   5348: @cindex Error Codes
                   5349: 
                   5350: @table @asis
                   5351: 
                   5352: @item @code{ZINRPT} - @emph{interrupt}
                   5353: Raised when an interrupt signal is received.
                   5354: 
                   5355: @item @code{ZBKERR} - @emph{BREAK point}
                   5356: Raised when a @code{BREAK} point is reached.
                   5357: 
                   5358: @item @code{ZNOSTAND} - @emph{non standard syntax}
                   5359: Raised when features incompatible with the current value of @code{$DIALECT} are used.
                   5360: 
                   5361: @item @code{ZUNDEF} - @emph{variable not found}
                   5362: Raised when an undefined local or global variable is accessed. This error code has been deprecated in favor of standard error codes @code{M6} and @code{M7}.
                   5363: 
                   5364: @item @code{ZLBLUNDEF} - @emph{label not found}
                   5365: Raised when a referenced label is not found.
                   5366: 
                   5367: @item @code{ZMISSOPD} - @emph{missing operand}
                   5368: Raised when an operand is missing from an expression.
                   5369: 
                   5370: @item @code{ZMISSOP} - @emph{missing operator}
                   5371: Raised when an operator is missing from an expression.
                   5372: 
                   5373: @item @code{ZILLOP} - @emph{unrecognized operator}
                   5374: Raised when an unrecognized operator is encountered in an expression.
                   5375: 
                   5376: @item @code{ZQUOTER} - @emph{unmatched quotes}
                   5377: Raised when unbalanced quotes are encountered.
                   5378: 
                   5379: @item @code{ZCOMMAER} - @emph{comma expected}
                   5380: Raised when a comma is expected in program syntax but is not found.
                   5381: 
                   5382: @item @code{ZASSIGNER} - @emph{equals '=' expected}
                   5383: Raised when an equals sign is expected in program syntax but is not found.
                   5384: 
                   5385: @item @code{ZARGER} - @emph{argument not permitted}
                   5386: Raised when an argument is encountered in a syntactic position where arguments are not permitted.
                   5387: 
                   5388: @item @code{ZSPACER} - @emph{blank ' ' expected}
                   5389: Raised when a space character is expected in program syntax but is not found.
                   5390: 
                   5391: @item @code{ZBRAER} - @emph{unmatched parentheses}
                   5392: Raised when unbalanced parentheses are detected in program syntax.
                   5393: 
                   5394: @item @code{ZLVLERR} - @emph{level error}
                   5395: Raised when a level error occurs.
                   5396: 
                   5397: @item @code{ZDIVER} - @emph{divide by zero}
                   5398: Raised when program code attempts to divide by zero. Deprecated in favor of standard error code @code{M9}.
                   5399: 
                   5400: @item @code{ZILLFUN} - @emph{function not found}
                   5401: Raised when program code attempts to call intrinsic or extrinsic functions that are not defined.
                   5402: 
                   5403: @item @code{ZFUNARG} - @emph{wrong number of function arguments}
                   5404: Raised when an intrinsic or extrinsic function is called with the wrong number of arguments.
                   5405: 
                   5406: @item @code{ZZTERR} - @emph{ZTRAP error}
                   5407: Raised when a @code{$ZTRAP} error occurs.
                   5408: 
                   5409: @item @code{ZNEXTERR} - @emph{$NEXT/$ORDER error}
                   5410: Raised when an error occurs in @code{$NEXT} or @code{$ORDER}.
                   5411: 
                   5412: @item @code{ZSELER} - @emph{$SELECT error}
                   5413: Raised when an error occurs in @code{$SELECT}
                   5414: 
                   5415: @item @code{ZCMMND} - @emph{illegal command}
                   5416: Raised when program code attempts to execute an illegal command.
                   5417: 
                   5418: @item @code{ZARGLIST} - @emph{argument list incorrect}
                   5419: Raised when the argument list supplied to an M language element does not match that language element's syntactic requirements.
                   5420: 
                   5421: @item @code{ZINVEXPR} - @emph{invalid expression}
                   5422: Raised when an invalid expression is encountered.
                   5423: 
                   5424: @item @code{ZINVREF} - @emph{invalid reference}
                   5425: Raised when an invalid variable reference is encountered.
                   5426: 
                   5427: @item @code{ZMXSTR} - @emph{string too long}
                   5428: Raised when a string is encountered that exceeds @code{^$SYSTEM("STRING_MAX")}.
                   5429: 
                   5430: @item @code{ZTOOPARA} - @emph{too many parameters}
                   5431: Raised when too many parameters are passed to a function or subroutine.
                   5432: 
                   5433: @item @code{ZNOPEN} - @emph{unit not open}
                   5434: Raised when attempting to access an I/O channel that has not been opened.
                   5435: 
                   5436: @item @code{ZNODEVICE} - @emph{unit does not exist}
                   5437: Raised when attempting to access a device that does not exist.
                   5438: 
                   5439: @item @code{ZPROTECT} - @emph{file protection violation}
                   5440: Raised when attempting to access a file or device to which you do not have permission.
                   5441: 
                   5442: @item @code{ZGLOBER} - @emph{global not permitted}
                   5443: Raised when attempting to use a global in a syntactic element where global variables are not permitted.
                   5444: 
                   5445: @item @code{ZFILERR} - @emph{file not found}
                   5446: Raised when attempting to access a file that does not exist.
                   5447: 
                   5448: @item @code{ZPGMOV} - @emph{program overflow}
                   5449: Raised when a program overflows the limits of a routine buffer.
                   5450: 
                   5451: @item @code{ZSTKOV} - @emph{stack overflow}
                   5452: Raised when @code{DO}, @code{FOR}, or @code{XECUTE} nesting levels exceed the value in @code{^$SYSTEM("NESTLEVLS")}.
                   5453: 
                   5454: @item @code{ZSTORE} - @emph{symbol table overflow}
                   5455: Raised when program code attempts to store too much data in the local symbol table. Should not occur unless symbol table auto-adjust is disabled.
                   5456: 
                   5457: @item @code{ZNOREAD} - @emph{file won't read}
                   5458: Raised when program code attempts to read from an unreadable file.
                   5459: 
                   5460: @item @code{ZNOWRITE} - @emph{file won't write}
                   5461: Raised when program code attempts to write to an unwritable file.
                   5462: 
                   5463: @item @code{ZNOPGM} - @emph{routine not found}
                   5464: Raised when an attempt is made to load or execute a routine that does not exist in the current namespace.
                   5465: 
                   5466: @item @code{ZNAKED} - @emph{illegal naked reference}
                   5467: Raised when an attempt is made to use an illegal naked reference.
                   5468: 
                   5469: @item @code{ZSBSCR} - @emph{illegal subscript}
                   5470: Raised when an illegal subscript access is attempted.
                   5471: 
                   5472: @item @code{ZISYNTX} - @emph{insert syntax}
                   5473: Raised when illegal insert syntax is used.
                   5474: 
                   5475: @item @code{ZDBDGD} - @emph{global data degradation}
                   5476: Raised when corruption is detected in global data files.
                   5477: 
                   5478: @item @code{ZKILLER} - @emph{job kill signal}
                   5479: Raised on a job kill signal.
                   5480: 
                   5481: @item @code{ZHUPER} - @emph{hangup signal}
                   5482: Raised on a job hangup signal.
                   5483: 
                   5484: @item @code{ZMXNUM} - @emph{numeric overflow}
                   5485: Raised when an assignment or expression result exceeds @code{$ZPRECISION}.
                   5486: 
                   5487: @item @code{ZNOVAL} - @emph{function returns no value}
                   5488: Raised when a function does not return a value. Extrinsic functions must @code{QUIT} with a value.
                   5489: 
                   5490: @item @code{ZTYPEMISMATCH} - @emph{type mismatch}
                   5491: Raised when a type mismatch occurs.
                   5492: 
                   5493: @item @code{ZMEMOV} - @emph{out of memory}
                   5494: Raised when FreeM runs out of heap memory.
                   5495: 
                   5496: @item @code{ZNAMERES} - @emph{error in name resolution}
                   5497: Raised when an attempted name resolution fails.
                   5498: 
                   5499: @item @code{ZSCKCREAT} - @emph{error creating socket}
                   5500: Raised when an error occurs creating a socket for network I/O.
                   5501: 
                   5502: @item @code{ZSCKIFAM} - @emph{invalid address family (must be IPV4 or IPV6)}
                   5503: Raised when the address family specified in an @code{OPEN} command for a socket I/O channel is not IPV4 or IPV6.
                   5504: 
                   5505: @item @code{ZSCKITYP} - @emph{invalid connection type (must be TCP or UDP)}
                   5506: Raised when the connection type specified in an @code{OPEN} command for a socket I/O channel is not @code{TCP} or @code{UDP}.
                   5507: 
                   5508: @item @code{ZSCKIPRT} - @emph{invalid port number}
                   5509: Raised when the port number specified in an @code{OPEN} command for a socket I/O channel is invalid. Valid TCP and UDP ports are in the range of 1-65535.
                   5510: 
                   5511: @item @code{ZSCKCERR} - @emph{connection error}
                   5512: Raised when an error occurs on a @code{USE <channel>:/CONNECT} command.
                   5513: 
                   5514: @item @code{ZSCKAERR} - @emph{USE action invalid for connection type (possibly CONNECT on UDP socket?)}
                   5515: Raised when an attempt is made to @code{USE <channel>:/CONNECT} on a UDP socket I/O channel. The UDP protocol is connectionless.
                   5516: 
                   5517: @item @code{ZSCKACON} - @emph{attempted to CONNECT an already-connected socket}
                   5518: Raised when an attempt is made to @code{USE <channel>:/CONNECT} on a TCP socket I/O channel that is already connected.
                   5519: 
                   5520: @item @code{ZSCKNCON} - @emph{attempted to READ from a disconnected TCP socket}
                   5521: Raised when an attempt is made to @code{READ} a TCP socket that has not yet been connected.
                   5522: 
                   5523: @item @code{ZSCKEOPT} - @emph{error setting socket options}
                   5524: Raised when an error is encountered while setting socket options.
                   5525: 
                   5526: @item @code{ZSCKERCV} - @emph{error in READ from socket}
                   5527: Raised when an error occurs in a socket I/O channel @code{READ}.
                   5528: 
                   5529: @item @code{ZSCKESND} - @emph{error in WRITE to socket}
                   5530: Raised when an error occurs while attempting to @code{WRITE} to a socket I/O channel.
                   5531: 
                   5532: @item @code{ZNORPI} - @emph{^$ZRPI only supported on Raspberry Pi hardware}
                   5533: Raised when an attempt is made to use the @code{^$ZRPI} structured system variable on a platform other than the Raspberry Pi single-board computer.
                   5534: 
                   5535: @item @code{ZCREDEF} - @emph{cannot redefine CONST}
                   5536: Raised when attempts are made to redefine a @code{CONST} after its initial definition.
                   5537: 
                   5538: @item @code{ZCMODIFY} - @emph{cannot modify CONST}
                   5539: Raised when attempts are made to change the value of a @code{CONST}.
                   5540: 
                   5541: @item @code{ZFILEXWR} - @emph{cannot open existing file for WRITE}
                   5542: Raised when an attempt is made to open an existing file in write (but not append) mode.
                   5543: 
                   5544: @item @code{INEWMULT} - @emph{initializing NEW with multiple setarguments not supported}
                   5545: Raised when you attempt to use multiple setarguments with initializing @code{NEW}, e.g. @code{NEW X=2,Y=3}.
                   5546: 
                   5547: @item @code{ZECODEINV} - @emph{invalid value for $ECODE}
                   5548: Raised when attempts are made to set @code{$ECODE} to an invalid error code value. Obsolete and replaced by standard error code @code{M101}.
                   5549: 
                   5550: @item @code{ZASSERT} - @emph{programmer assertion failed}
                   5551: Raised when an @code{ASSERT} expression's result is not true.
                   5552: 
                   5553: @item @code{ZUSERERR} - @emph{user-defined error}
                   5554: Raised when program code calls @code{THROW} with an error code argument for which the first character is @code{U}, or when @code{$ECODE} is set to an error code for which the first character is @code{U}.
                   5555: 
                   5556: Custom error messages for @code{ZUSERERR} may be set in @code{^$JOB($JOB,"USER_ERRORS",<user_error_code>)}, where @code{<user_error_code>} represents the custom error code.
                   5557: 
                   5558: For example:
                   5559: 
                   5560: @example
1.22      snw      5561: DEFAULT.USER> S ^$JOB($JOB,"USER_ERRORS","UBLACKHOLE")="black hole encountered"
1.1       snw      5562: 
                   5563: 
1.22      snw      5564: DEFAULT.USER> THROW UBLACKHOLE
1.1       snw      5565: 
                   5566: 
                   5567: >> Error UBLACKHOLE:  black hole encountered in SYSTEM::^%SYSINIT  [$STACK = 0]
                   5568: >> THROW UBLACKHOLE
                   5569:                   ^
                   5570: @end example
                   5571: 
                   5572: @item @code{ZSYNTERR} - @emph{syntax error}
                   5573: Raised when a syntax error without a more specific error code is encountered.
                   5574: 
                   5575: @item @code{ZCTRLB} - @emph{break}
                   5576: Pseudo-error used by the FreeM debugger. Not visibly raised in normal program operation.
                   5577: 
                   5578: @item @code{ZASYNC} - @emph{asynchronous interruption}
                   5579: Pseudo-error used by the FreeM asynchronous events subsystem. Not visibly raised in normal program operation.
                   5580: 
                   5581: @item @code{M1} - @emph{naked indicator undefined}
                   5582: Raised when an attempt is made to use a naked reference before the naked indicator is set.
                   5583: 
                   5584: @item @code{M2} - @emph{invalid combination with $FNUMBER code atom}
                   5585: 
                   5586: 
                   5587: @item @code{M3} - @emph{$RANDOM seed less than 1}
                   5588: 
                   5589: 
                   5590: @item @code{M4} - @emph{no true condition in $SELECT}
                   5591: 
                   5592: 
                   5593: @item @code{M5} - @emph{line reference less than zero}
                   5594: 
                   5595: 
                   5596: @item @code{M6} - @emph{undefined local variable}
                   5597: 
                   5598: 
                   5599: @item @code{M7} - @emph{undefined global variable}
                   5600: 
                   5601: 
                   5602: @item @code{M8} - @emph{undefined intrinsic special variable}
                   5603: 
                   5604: 
                   5605: @item @code{M9} - @emph{divide by zero}
                   5606: 
                   5607: 
                   5608: @item @code{M10} - @emph{invalid pattern match range}
                   5609: 
                   5610: 
                   5611: @item @code{M11} - @emph{no parameters passed}
                   5612: 
                   5613: 
                   5614: @item @code{M12} - @emph{invalid line reference (negative offset)}
                   5615: 
                   5616: 
                   5617: @item @code{M13} - @emph{invalid line reference (line not found)}
                   5618: 
                   5619: 
                   5620: @item @code{M14} - @emph{line level not 1}
                   5621: 
                   5622: 
                   5623: @item @code{M15} - @emph{undefined index variable}
                   5624: 
                   5625: 
                   5626: @item @code{M16} - @emph{argumented QUIT not allowed}
                   5627: 
                   5628: 
                   5629: @item @code{M17} - @emph{argumented QUIT required}
                   5630: 
                   5631: 
                   5632: @item @code{M18} - @emph{fixed length READ not greater than zero}
                   5633: 
                   5634: 
                   5635: @item @code{M19} - @emph{cannot copy a tree or subtree onto itself}
                   5636: 
                   5637: 
                   5638: @item @code{M20} - @emph{line must have a formal parameter list}
                   5639: 
                   5640: 
                   5641: @item @code{M21} - @emph{algorithm specification invalid}
                   5642: 
                   5643: 
                   5644: @item @code{M22} - @emph{SET or KILL to ^$GLOBAL when data in global}
                   5645: 
                   5646: 
                   5647: @item @code{M23} - @emph{SET or KILL to ^$JOB for non-existent job number}
                   5648: 
                   5649: 
                   5650: @item @code{M24} - @emph{change to collation algorithm while subscripted local variables defined}
                   5651: 
                   5652: 
                   5653: @item @code{M26} - @emph{non-existent environment}
                   5654: 
                   5655: 
                   5656: @item @code{M27} - @emph{attempt to rollback a transaction that is not restartable}
                   5657: 
                   5658: 
                   5659: @item @code{M28} - @emph{mathematical function, parameter out of range}
                   5660: 
                   5661: 
                   5662: @item @code{M29} - @emph{SET or KILL on structured system variable not allowed by implementation}
                   5663: 
                   5664: 
                   5665: @item @code{M30} - @emph{reference to global variable with different collating sequence within a collating algorithm}
                   5666: 
                   5667: 
                   5668: @item @code{M31} - @emph{control mnemonic used for device without a mnemonic space selected}
                   5669: 
                   5670: 
                   5671: @item @code{M32} - @emph{control mnemonic used in user-defined mnemonic space which has no associated line}
                   5672: 
                   5673: 
                   5674: @item @code{M33} - @emph{SET or KILL to ^$ROUTINE when routine exists}
                   5675: 
                   5676: 
                   5677: @item @code{M35} - @emph{device does not support mnemonic space}
                   5678: 
                   5679: 
                   5680: @item @code{M36} - @emph{incompatible mnemonic spaces}
                   5681: 
                   5682: 
                   5683: @item @code{M37} - @emph{READ from device identified by empty string}
                   5684: 
                   5685: 
                   5686: @item @code{M38} - @emph{invalid structured system variable subscript}
                   5687: 
                   5688: 
                   5689: @item @code{M39} - @emph{invalid $NAME argument}
                   5690: 
                   5691: 
                   5692: @item @code{M40} - @emph{call-by-reference in JOB actual parameter}
                   5693: 
                   5694: 
                   5695: @item @code{M41} - @emph{invalid LOCK argument within a transaction}
                   5696: 
                   5697: 
                   5698: @item @code{M42} - @emph{invalid QUIT within a transaction}
                   5699: 
                   5700: 
                   5701: @item @code{M43} - @emph{invalid range value ($X, $Y}
                   5702: 
                   5703: 
                   5704: @item @code{M44} - @emph{invalid command outside of a transaction}
                   5705: 
                   5706: 
                   5707: @item @code{M45} - @emph{invalid GOTO reference}
                   5708: 
                   5709: 
                   5710: @item @code{M56} - @emph{identifier exceeds maximum length}
                   5711: 
                   5712: 
                   5713: @item @code{M57} - @emph{more than one defining occurrence of label in routine}
                   5714: 
                   5715: 
                   5716: @item @code{M58} - @emph{too few formal parameters}
                   5717: 
                   5718: 
                   5719: @item @code{M60} - @emph{illegal attempt to use an undefined SSVN}
                   5720: 
                   5721: 
                   5722: @item @code{M101} - @emph{invalid value for $ECODE}
                   5723: 
                   5724: 
                   5725: @item @code{M102} - @emph{synchronous and asynchronous event processing cannot be simultaneously enabled for the same event class}
                   5726: 
                   5727: 
                   5728: @item @code{M103} - @emph{invalid event identifier}
                   5729: 
                   5730: 
                   5731: @item @code{M104} - @emph{ETRIGGER event identifier for IPC event class does not match job process identifier}
                   5732: 
                   5733: 
                   5734: @end table
                   5735: 
1.35      snw      5736: 
1.1       snw      5737: @node System Configuration
                   5738: @chapter System Configuration
                   5739: @cindex configuration, system
                   5740: 
                   5741: @section Installing FreeM
                   5742: @cindex installation
                   5743: 
1.35      snw      5744: @subsection Installation Methods
1.1       snw      5745: 
1.35      snw      5746: FreeM allows the following installation methods:
1.1       snw      5747: @table @asis
1.35      snw      5748: @item Binary Repository
                   5749: On recent versions the Ubuntu and Debian distributions of GNU/Linux, we provide package repositories from which FreeM may easily be installed. See the @emph{FreeM Wiki} for more information, and @emph{https://packages.coherent-logic.com} for instructions.
1.1       snw      5750: 
1.35      snw      5751: If available, this is the simplest method of installing FreeM.
                   5752: @item Binary Packages
                   5753: We provide binary packages of FreeM for @emph{dpkg} and @emph{rpm}-based distributions of GNU/Linux, and @emph{pkgadd} packages for Solaris 8-10. If you cannot use repositories, this is the easiest option.
                   5754: 
                   5755: See @emph{https://freem.coherent-logic.com/binaries.cfm} for downloads and instructions.
                   5756: @item Source Archive
                   5757: If you prefer installing from source, we recommend that you download the latest @emph{.tar.gz} file from @emph{https://freem.coherent-logic.com/downloads.cfm}, and follow these steps:
                   5758: 
                   5759: @example
                   5760: $ gunzip freem-@emph{<version>}.tar.gz
                   5761: $ tar xf freem-@emph{<version>}.tar
                   5762: $ cd freem
                   5763: $ ./configure # see the Build Configuration section for optional flags
                   5764: $ make
                   5765: $ sudo make install
                   5766: @end example
1.1       snw      5767: 
1.35      snw      5768: Once this process has been completed, you may proceed to @emph{Initial Configuration}.
1.1       snw      5769: 
1.35      snw      5770: Installation from source archive is the most challenging but flexible supported option for advanced users.
                   5771: @item CVS Repository
                   5772: If you wish to try the bleeding-edge development version of FreeM, you may do so by following these steps:
1.1       snw      5773: 
1.35      snw      5774: @verbatim
                   5775: $ cvs -d :pserver:anonymous@cvs.coherent-logic.com:/home/cvsroot co freem
                   5776: $ cd freem
                   5777: $ ./autogen.sh
                   5778: $ ./configure # see the Build Configuration section for optional flags
1.1       snw      5779: $ make
                   5780: $ sudo make install
1.35      snw      5781: @end verbatim
                   5782: 
                   5783: Once this process has been completed, you may proceed to @emph{Initial Configuration}.
                   5784: 
                   5785: This installation method is by far the most complicated, and is intended only for those who wish to contribute to FreeM development. It is not intended for end users, and no technical support will be provided.
                   5786: 
                   5787: See the @emph{Contributor Guide} on the @emph{FreeM Wiki} for more information.
                   5788: @end table
                   5789: @subsection Build Configuration
                   5790: @cindex build configuration
                   5791: 
                   5792: When configuring FreeM with the supplied @code{configure} script, there are some FreeM-specific options that may be used to compile in optional features, or exclude default ones:
                   5793: 
                   5794: @table @asis
1.1       snw      5795: 
1.35      snw      5796: @item @code{--enable-mwapi} (EXPERIMENTAL)
                   5797: Enables experimental support for the M Windowing API (ANSI @emph{X11.6-1995}) using the OSF/Motif widget toolkit. Requires that you have the @code{X11}, @code{Xt}, @code{ICE}, and @code{Xm} libraries, as well as all of their C header files.
1.1       snw      5798: 
                   5799: Please consult your operating system's documentation for the correct commands to install the required libraries.
                   5800: 
                   5801: @emph{Example}
                   5802: 
                   5803: @example
1.35      snw      5804: $ ./configure --enable-mwapi
1.1       snw      5805: $ make
                   5806: $ sudo make install
                   5807: @end example
                   5808: 
1.35      snw      5809: @end table
1.1       snw      5810: 
1.35      snw      5811: @subsection Initial Configuration
                   5812: Once FreeM is installed, you will need to configure it:
1.1       snw      5813: 
1.35      snw      5814: @enumerate
                   5815: @item Create a user and group, each named @emph{freem}, under which FreeM will run
                   5816: @item Add any user accounts that will need to run FreeM to the @emph{freem} group
                   5817: @item Have all users added in step 2 sign out and sign in for the new group membership to take effect 
                   5818: @item Run @code{fmadm configure} with superuser privileges to create the @code{DEFAULT} environment with @code{SYSTEM} and @code{USER} namespaces and default after-image journal settings, and populate the bundled vendor routines
                   5819: @item Run @code{fmadm start environment} with superuser privileges to start the @code{DEFAULT} environment
                   5820: @item Make sure the environment is ready by running @code{fmadm status environment} with superuser privileges
                   5821: @end enumerate
                   5822: 
                   5823: @subsubsection Creating Additional Environments
                   5824: To create additional environments, do the following steps:
                   5825: 
                   5826: @enumerate
                   5827: @item Create a new user and group for the environment @emph{(optional)}
                   5828: @item Run @code{fmadm configure -e=@emph{<environment>} -u=@emph{<username>} -g=@emph{<groupname>} [-E=@emph{true|false}]} @emph{(the @code{-E} flag enables or disables the environment)}
                   5829: @item Run @code{fmadm start environment -e=@emph{<environment>}} to start the environment
                   5830: @item Run @code{fmadm status environment} to make sure the environment is healthy
                   5831: @end enumerate
1.1       snw      5832: 
1.35      snw      5833: @subsubsection Additional Customization
1.1       snw      5834: 
1.35      snw      5835: See the FreeM @emph{environment catalog} at @code{@emph{$PREFIX}/etc/freem/env.conf}, and the @emph{fmadm}(1) @code{man} page for more information.
1.1       snw      5836: 
1.35      snw      5837: @emph{$PREFIX} represents the root location of your FreeM installation. This can be @code{/usr/local}, @code{/}, or others, depending on how FreeM was built and installed.
1.1       snw      5838: 
                   5839: @node Accessing FreeM from C Programs
                   5840: @chapter Accessing FreeM from C Programs
                   5841: 
                   5842: FreeM provides a library, @file{libfreem.so}, as well as corresponding header file @file{freem.h}, allowing C programmers to write programs that access FreeM globals, locals, structured system variables, subroutines, and extrinsic functions. This functionality can be used to implement language bindings and data access drivers for external systems.
                   5843: 
                   5844: In order to be used in your C programs, your C programs must link with @file{libfreem.so} and include @file{freem.h}. This will allow your C code access to the function prototypes, data structures, and constants required for calling the @file{libfreem.so} APIs.
                   5845: 
                   5846: You must exercise caution in developing programs that interface with FreeM through @file{libfreem.so} to ensure that all @file{libfreem.so} API calls are serialized, as FreeM and the @file{libfreem.so} library are neither thread-safe nor reentrant.
                   5847: 
                   5848: You must also avoid setting signal handlers for @code{SIGALRM}, as FreeM uses @code{SIGALRM} to manage timeouts for @command{LOCK}, @command{READ}, and @command{WRITE}.
                   5849: 
                   5850: @section freem_ref_t Data Structure
                   5851: @cindex libfreem, data structures: freem_ref_t
                   5852: 
                   5853: The @code{libfreem} API uses a @code{struct} of type @code{freem_ref_t} in order to communicate state, pass in values, and return results.
                   5854: 
                   5855: The data structure, defined in @file{freem.h}, looks like this:
                   5856: 
                   5857: @verbatim
                   5858: typedef struct freem_ref_t {
                   5859: 
                   5860:     /*
                   5861:      * The 'reftype' field can be one of:
                   5862:      * 
                   5863:      *  MREF_RT_LOCAL
                   5864:      *  MREF_RT_GLOBAL
                   5865:      *  MREF_RT_SSV
                   5866:      */
                   5867:     short reftype;
                   5868: 
                   5869:     /*
                   5870:      * The 'name' field is the name of the local variable,
                   5871:      * global variable, or SSVN (without ^ or ^$).
                   5872:      */
                   5873:     char name[256];    
                   5874: 
                   5875:     /*
                   5876:      * Returned data goes in a string, so you've got to figure out the
                   5877:      * whole M canonical number thing yourself. Good luck. :-)
                   5878:      */
                   5879:     char value[STRLEN];   
                   5880: 
                   5881:     short status;
                   5882: 
                   5883:     unsigned int subscript_count;
                   5884:     char subscripts[255][256];
                   5885: 
                   5886: } freem_ref_t;
                   5887: @end verbatim
                   5888: 
                   5889: @emph{freem_ref_t Members}
                   5890: 
                   5891: @table @asis
                   5892: @cindex libfreem, freem_ref_t.reftype
                   5893: @item @option{reftype}
                   5894: The @option{reftype} member determines whether we are operating on a local variable, a global variable, or a structured system variable. It may be set to any of following constants: @code{MREF_RT_LOCAL}, @code{MREF_RT_GLOBAL}, or @code{MREF_RT_SSV}.
                   5895: 
                   5896: @cindex libfreem, freem_ref_t.name
                   5897: @item @option{name}
                   5898: The @option{name} member contains the name of the global, local, or SSVN to be accessed. You @emph{must not} include leading characters, such as @code{^} or @code{^$}.
                   5899: 
                   5900: @cindex libfreem, freem_ref_t.value
                   5901: @item @option{value}
                   5902: This member contains the value read from or the value to be written to the global, local, or SSVN.
                   5903: 
                   5904: @cindex libfreem, freem_ref_t.status
                   5905: @item @option{status}
                   5906: This member gives us various API status values after the API call returns. In general, this value is also returned by each API function.
                   5907: 
                   5908: @cindex libfreem, freem_ref_t.subscript_count
                   5909: @item @option{subscript_count}
                   5910: The number of subscripts to be passed into the API function being called. This value represents the maximum index into the first dimension of the @code{subscripts} array.
                   5911: 
                   5912: @cindex libfreem, freem_ref_t.subscripts
                   5913: @item @option{subscripts}
                   5914: A two-dimensional array containing the subscripts to which we are referring in this API call. 
                   5915: 
                   5916: @end table
                   5917: 
                   5918: @section freem_ent_t Data Structure
                   5919: @cindex libfreem, data structures: freem_ent_t
                   5920: 
                   5921: The @code{freem_function()} and @code{freem_procedure()} APIs in @code{libfreem} use the @code{freem_ent_t} struct in order to indicate the name of the entry point being called, any arguments being passed to it, and the return value of the called function (not used for @code{freem_procedure()}).
                   5922: 
                   5923: The data structure, defined in @file{freem.h}, looks like this:
                   5924: 
                   5925: @verbatim
                   5926: typedef struct freem_ent_t {
                   5927: 
                   5928:     /* name of function or procedure entry point */
                   5929:     char name[256];
                   5930: 
                   5931:     /* return value */
                   5932:     char value[STRLEN];
                   5933: 
                   5934:     /* value of ierr on return */
                   5935:     short status;
                   5936: 
                   5937:     /* argument count and array */
                   5938:     unsigned int argument_count;
                   5939:     char arguments[255][256];
                   5940: 
                   5941: } freem_ent_t;
                   5942: @end verbatim
                   5943: 
                   5944: @emph{freem_ent_t Members}
                   5945: 
                   5946: @table @asis
                   5947: 
                   5948: @item @option{name}
                   5949: @cindex libfreem, freem_ent_t.name
                   5950: The @option{name} member contains the name of the extrinsic function or procedure to be called.
                   5951: 
                   5952: @cindex libfreem, freem_ent_t.value
                   5953: @item @option{value}
                   5954: This member contains the value returned by the function called. Not used by @code{freem_procedure()}. 
                   5955: 
                   5956: @cindex libfreem, freem_ent_t.status
                   5957: @item @option{status}
                   5958: This member gives us the value of @code{ierr} after the function or procedure call returns. The possible values of @code{ierr} are listed in @code{merr.h}.
                   5959: 
                   5960: @cindex libfreem, freem_ent_t.argument_count
                   5961: @item @option{argument_count}
                   5962: The number of arguments to be passed into the extrinsic function or procedure being called. This value represents the maximum index into the first dimension of the @code{arguments} array.
                   5963: 
                   5964: @cindex libfreem, freem_ent_t.arguments
                   5965: @item @option{arguments}
                   5966: A two-dimensional array containing the arguments to be passed into the extrinsic function or procedure being called.
                   5967: 
                   5968: @end table
                   5969: 
                   5970: @section freem_init()
                   5971: @cindex libfreem, freem_init()
                   5972: 
                   5973: Initializes @code{libfreem} in preparation for calling other APIs.
                   5974: 
                   5975: @emph{Synopsis}
                   5976: 
                   5977: @code{pid_t freem_init(char *environment_name, char *namespace_name);}
                   5978: 
                   5979: @emph{Parameters}
                   5980: 
                   5981: @table @asis
                   5982: @item @code{environment_name}
                   5983: Specifies the environment to use.
                   5984: @item @code{namespace_name}
                   5985: Specifies the namespace to use.
                   5986: @end table
                   5987: 
                   5988: @emph{Return Values}
                   5989: 
                   5990: Returns the process ID of the @code{libfreem} process on success, or @code{-1} on failure.
                   5991: 
                   5992: @emph{Example}
                   5993: 
                   5994: This example prompts the user to enter a FreeM namespace and then attempts to initialize @code{libfreem} to use the selected namespace.
                   5995: 
                   5996: @verbatim
                   5997: #include <stdio.h>
                   5998: #include <string.h>
                   5999: #include <freem.h>
                   6000: 
                   6001: int main(int argc, char **argv, char **envp)
                   6002: {
                   6003:     char namespace[256];
                   6004: 
                   6005:     /* get the namespace name to use */
                   6006:     printf("Enter FreeM namespace to use: ");
                   6007:     fgets(namespace, 255, stdin);
                   6008: 
                   6009:     /* remove the trailing newline */
                   6010:     namespace[strcspn(buffer, "\n")] = '\0';
                   6011: 
                   6012:     /* initialize libfreem using the provided namespace */
                   6013:     if(freem_init("DEFAULT", namespace) == TRUE) {
                   6014:         printf("\nSuccess\n");
                   6015:     }
                   6016:     else {
                   6017:         printf("\nFailure\n");
                   6018:     }
                   6019:      
                   6020:     return 0;
                   6021: }
                   6022: @end verbatim
                   6023: 
                   6024: @section freem_version()
                   6025: @cindex libfreem, freem_version()
                   6026: 
                   6027: Returns the version of FreeM in use.
                   6028: 
                   6029: @emph{Synopsis}
                   6030: 
                   6031: @code{short freem_version(char *result);}
                   6032: 
                   6033: @emph{Parameters}
                   6034: 
                   6035: @table @asis
                   6036: @item @code{result}
                   6037: The @code{result} parameter is a pointer to a buffer in which the FreeM version information will be returned. The caller must allocate memory for this buffer prior to calling this API. It should be at least 20 bytes in length.
                   6038: @end table
                   6039: 
                   6040: @emph{Return Value}
                   6041: 
                   6042: Returns @code{0}.
                   6043: 
                   6044: @emph{Example}
                   6045: 
                   6046: This example will display the FreeM version on standard output.
                   6047: 
                   6048: @verbatim
                   6049: #include <stdio.h>
                   6050: #include <string.h>
                   6051: #include <freem.h>
                   6052: 
                   6053: int main(int argc, char **argv, char **envp)
                   6054: {
                   6055:     char version[20] = {0};
                   6056: 
                   6057:     freem_init(``USER'');
                   6058:     freem_version(version);
                   6059: 
                   6060:     printf(``FreeM version:  %s\n'', version);
                   6061: 
                   6062: }
                   6063: @end verbatim
                   6064: 
                   6065: @section freem_set()
                   6066: @cindex libfreem, freem_set()
                   6067: 
                   6068: Sets a FreeM local node, global node, or writable SSVN node. 
                   6069: 
                   6070: @emph{Synopsis}
                   6071: 
                   6072: @code{short freem_set(freem_ref_t *ref);}
                   6073: 
                   6074: @emph{Parameters}
                   6075: 
                   6076: @table @asis
                   6077: @item @code{freem_ref_t}
                   6078: This parameter is a pointer to a @code{freem_ref_t} struct. The caller must allocate the memory for this struct.
                   6079: @end table
                   6080: 
                   6081: @emph{Return Value}
                   6082: 
                   6083: Returns @code{OK} on success, or one of the other error values defined in @code{merr.h}.
                   6084: 
                   6085: @emph{Example}
                   6086: 
                   6087: This example sets the value @code{blue} into global node @code{^car("color")}.
                   6088: 
                   6089: @verbatim
                   6090: #include <stdio.h>
                   6091: #include <string.h>
                   6092: #include <freem.h>
                   6093: 
                   6094: int main(int argc, char **argv, char **envp)
                   6095: {
                   6096:     freem_ref_t ref;
                   6097: 
                   6098:     /* we're setting a global */
                   6099:     ref.reftype = MREF_RT_GLOBAL;
                   6100: 
                   6101:     /* access global "car" */
                   6102:     strcpy(ref.name, "car");
                   6103: 
                   6104:     /* set up the subscripts */
                   6105:     ref.subscript_count = 1;
                   6106:     strcpy(ref.subscripts[0], "color");
                   6107:  
                   6108: 
                   6109:     /* use the USER namespace */
                   6110:     freem_init("USER");
                   6111: 
                   6112:     /* write the data out */
                   6113:     freem_set(&ref);
                   6114:     
                   6115: }
                   6116: @end verbatim
                   6117: 
                   6118: @section freem_get()
                   6119: @cindex libfreem, freem_get()
                   6120: 
                   6121: Retrieves a FreeM local node, global node, or writable SSVN node.
                   6122: 
                   6123: @emph{Synopsis}
                   6124: 
                   6125: @code{short freem_get(freem_ref_t *ref);}
                   6126: 
                   6127: @emph{Parameters}
                   6128: 
                   6129: @table @asis
                   6130: @item @code{freem_ref_t}
                   6131: This parameter is a pointer to a @code{freem_ref_t} struct. The caller must allocate the memory for this struct.
                   6132: @end table
                   6133: 
                   6134: @emph{Return Value}
                   6135: 
                   6136: Returns @code{OK} on success, or one of the other error values defined in @code{merr.h}.
                   6137: 
                   6138: @emph{Example}
                   6139: 
                   6140: This example retrieves the character set of the current process.
                   6141: 
                   6142: @verbatim
                   6143: #include <stdio.h>
                   6144: #include <sys/types.h>
                   6145: #include <unistd.h>
                   6146: #include <string.h>
                   6147: #include <freem.h>
                   6148: 
                   6149: int main(int argc, char **argv, char)
                   6150: {
                   6151:     pid_t pid;
                   6152:     freem_ref_t ref;
                   6153: 
                   6154:     /* get the PID of this process */
                   6155:     pid = getpid();
                   6156: 
                   6157:     /* we want to access an SSVN */
                   6158:     ref.reftype = MREF_RT_SSV;
                   6159:     
                   6160:     /* set up the name and subscripts */
                   6161:     strcpy(ref.name, "JOB");
                   6162: 
                   6163:     ref.subscript_count = 2;
                   6164:     sprintf(ref.subscripts[0], "%d", pid);
                   6165:     strcpy(ref.subscripts[1], "CHARACTER");
                   6166: 
                   6167:     /* initialize libfreem, using the USER namespace */
                   6168:     freem_init("USER");
                   6169: 
                   6170:     /* call libfreem API */
                   6171:     freem_get(&ref);
                   6172: 
                   6173:     /* output the character set info */
                   6174:     printf("PID %d character set is '%s'\n", pid, ref.value);
                   6175: }
                   6176: @end verbatim
                   6177: 
                   6178: @section freem_kill()
                   6179: @cindex libfreem, freem_kill()
                   6180: 
                   6181: Deletes a FreeM local node, global node, or killable SSVN node, as well as all of its children.
                   6182: 
                   6183: @emph{short freem_kill(freem_ref_t *ref);}
                   6184: 
                   6185: @emph{Parameters}
                   6186: 
                   6187: @table @asis
                   6188: @item @code{freem_ref_t}
                   6189: This parameter is a pointer to a @code{freem_ref_t} struct. The caller must allocate the memory for this struct.
                   6190: @end table
                   6191: 
                   6192: @emph{Return Value}
                   6193: 
                   6194: Returns @code{OK} on success, or one of the other error values defined in @code{merr.h}.
                   6195: 
                   6196: @emph{Example}
                   6197: 
                   6198: @verbatim
                   6199: #include <stdio.h>
                   6200: #include <string.h>
                   6201: #include <freem.h>
                   6202: 
                   6203: int main(int argc, char **argv, char **envp)
                   6204: {
                   6205:     freem_ref_t ref;
                   6206: 
                   6207:     /* we're killing a global node */
                   6208:     ref.reftype = MREF_RT_GLOBAL;
                   6209: 
                   6210:     /* access global "car" */
                   6211:     strcpy(ref.name, "car");
                   6212: 
                   6213:     /* set up the subscripts */
                   6214:     ref.subscript_count = 0;
                   6215: 
                   6216:     /* use the USER namespace */
                   6217:     freem_init("USER");
                   6218: 
                   6219:     /* kill the global and all its descendant subscripts */
                   6220:     freem_kill(&ref);    
                   6221: }
                   6222: @end verbatim
                   6223: 
                   6224: @section freem_data()
                   6225: @cindex libfreem, freem_data()
                   6226: 
                   6227: @section freem_order()
                   6228: @cindex libfreem, freem_order()
                   6229: 
                   6230: @section freem_query()
                   6231: @cindex libfreem, freem_query()
                   6232: 
                   6233: @section freem_lock()
                   6234: @cindex libfreem, freem_lock()
                   6235: 
                   6236: @section freem_unlock()
                   6237: @cindex libfreem, freem_unlock()
                   6238: 
                   6239: @section freem_tstart()
                   6240: @cindex libfreem, freem_tstart()
                   6241: 
                   6242: @section freem_trestart()
                   6243: @cindex libfreem, freem_trestart()
                   6244: 
                   6245: @section freem_trollback()
                   6246: @cindex libfreem, freem_trollback()
                   6247: 
                   6248: @section freem_tlevel()
                   6249: @cindex libfreem, freem_tlevel()
                   6250: 
                   6251: @section freem_tcommit()
                   6252: @cindex libfreem, freem_tcommit()
                   6253: 
                   6254: @section freem_function()
                   6255: @cindex libfreem, freem_function()
                   6256: 
                   6257: @section freem_procedure()
                   6258: @cindex libfreem, freem_procedure()
                   6259: 
                   6260: @node FreeM Administrator
                   6261: @appendix FreeM Administrator
                   6262: @cindex utilities, system management
                   6263: @cindex utilities, fmadm
                   6264: @cindex fmadm
                   6265: 
                   6266: The @code{fmadm} utility is the preferred method of managing a FreeM installation, and will eventually replace all of the existing utilities.
                   6267: Unlike the existing, legacy utilities, @code{fmadm} presents a consistent, simple interface for all FreeM management tasks, and is namespace-aware.
                   6268: This appendix will document each @code{fmadm} facility as it is implemented, until all of the legacy utilities have been replaced.
                   6269: 
                   6270: The @code{fmadm} utility's functions all follow the below, consistent syntax:
                   6271: 
                   6272: @example
                   6273: usage:  fmadm <action> <object> <namespace> [OPTIONS]
                   6274: @end example
                   6275: 
                   6276: The @emph{action} keyword can be one of the following:
                   6277: 
                   6278: @table @emph
                   6279: 
                   6280: @item list
                   6281: Lists instances of @emph{object}
                   6282: 
                   6283: @item examine
                   6284: Examines a single instance of @emph{object}
                   6285: 
                   6286: @item verify
                   6287: Verifies the integrity of @emph{object}
                   6288: 
                   6289: @item compact
                   6290: Compacts @emph{object}
                   6291: 
                   6292: @item repair
                   6293: Repairs integrity problems in @emph{object}
                   6294: 
                   6295: @item create
                   6296: Creates an instance of @emph{object}
                   6297: 
                   6298: @item remove
                   6299: Removes an instance of @emph{object}
                   6300: 
                   6301: @item import
                   6302: Imports an @emph{object}
                   6303: 
                   6304: @item export
                   6305: Exports an @emph{object}
                   6306: 
                   6307: @item backup
                   6308: Creates a backup of @emph{object}
                   6309: 
                   6310: @item restore
                   6311: Restores a backup of @emph{object}
                   6312: 
                   6313: @item migrate
                   6314: Migrates an instance of @emph{object} from an older FreeM version to the current version
                   6315: 
                   6316: @item edit
                   6317: Edits an instance of @emph{object}
                   6318: 
                   6319: @end table
                   6320: 
                   6321: The @emph{object} keyword can be one of the following:
                   6322: 
                   6323: @table @emph
                   6324: 
                   6325: @item lock
                   6326: The FreeM @code{LOCK} table.
                   6327: 
                   6328: Supported actions are @code{list} and @code{remove}.
                   6329: 
                   6330: @item journal
                   6331: FreeM after-image journaling.
                   6332: 
                   6333: Supported actions are @code{examine} and @code{restore}.
                   6334: 
                   6335: The @code{examine} action will dump the after-image journal entries for the selected namespace in human-readable format.
                   6336: 
                   6337: The @code{restore} action will play after-image journals forward for the selected namespace.
                   6338: 
                   6339: @item namespace
                   6340: FreeM namespaces (collections of M routines and globals).
                   6341: 
                   6342: No actions yet implemented.
                   6343: 
                   6344: @item global
                   6345: The data files representing each FreeM @emph{global}.
                   6346: 
                   6347: Supported actions are @code{list}, @code{examine}, @code{remove}, and @code{verify}.
                   6348: 
                   6349: @item routine
                   6350: An M routine, stored as a @code{.m} file.
                   6351: 
                   6352: Supported actions are @code{list}, @code{examine}, @code{remove}, @code{import}, @code{export}, @code{backup}, and @code{edit}.
                   6353: 
                   6354: @item job
                   6355: A UNIX process representing an instance of the FreeM runtime.
                   6356: 
                   6357: Supported actions are @code{list} and @code{examine}.
                   6358: 
                   6359: @end table
                   6360: 
                   6361: 
                   6362: @node FreeM Legacy Utilities
                   6363: @appendix FreeM Legacy Utilities
                   6364: @cindex utilities, legacy
                   6365: 
                   6366: @section Global Compactor (gcompact)
                   6367: @cindex utilities, legacy, gcompact
                   6368: 
                   6369: Compacts the specified global in place.
                   6370: 
                   6371: @emph{Syntax}
                   6372: 
                   6373: @example
                   6374: gcompact @emph{/path/to/global/file}
                   6375: @end example
                   6376: 
                   6377: @section Block Examiner (gfix)
                   6378: @cindex utilities, gfix
                   6379: 
                   6380: The @emph{gfix} interactive utility program permits navigation of the B-tree structure of the specified global a block at a time.
                   6381: 
                   6382: @emph{Syntax}
                   6383: 
                   6384: @example
                   6385: gfix @emph{</path/to/global/file>}
                   6386: @end example
                   6387: 
                   6388: @section Global Repair Tool (grestore)
                   6389: @cindex utilities, legacy, grestore
                   6390: 
                   6391: This utility will fix problems with the specified global.
                   6392: 
                   6393: @emph{Syntax}
                   6394: 
                   6395: @example
                   6396: grestore @emph{</path/to/global/file>}
                   6397: @end example
                   6398: 
                   6399: @node FreeM VIEW Commands and Functions
                   6400: @appendix FreeM VIEW Commands and Functions
                   6401: 
                   6402: @section VIEW 16: Total Count of Error Messages/View Single Error Message
                   6403: @cindex VIEW commands/functions, 16, total count of error messages/view single error message
                   6404: 
                   6405: Unknown semantics
                   6406: 
                   6407: @section VIEW 17: Intrinsic Z-Commands
                   6408: @cindex VIEW commands/functions, 17, intrinsic Z-commands
                   6409: 
                   6410: Allows the user to retrieve or specify the list of intrinsic Z-commands that FreeM will attempt to run internally, allowing intrinsic Z-commands implemented internally to be replaced with M equivalents implemented as %-routines in the @code{SYSTEM} namespace.
                   6411: 
                   6412: @section VIEW 18: Intrinsic Z-Functions
                   6413: @cindex VIEW commands/functions, 18, intrinsic Z-functions
                   6414: 
                   6415: Allows the user to retrieve or specify the list of intrinsic Z-functions that FreeM will attempt to run internally, allowing intrinsic Z-functions implemented internally to be replaced with M equivalents implemented as %-routines in the @code{SYSTEM} namespace.
                   6416: 
                   6417: @section VIEW 19: Intrinsic Special Variables
                   6418: @cindex VIEW commands/functions, 19, intrinsic special variables
                   6419: 
                   6420: Allows the user to retrieve or specify which special variables are implemented internally.
                   6421: 
                   6422: @section VIEW 20: Break Service Code
                   6423: @cindex VIEW commands/functions, 20, break service code
                   6424: 
                   6425: Allows the user to view or specify the code that will be run when a @code{BREAK} is encountered.
                   6426: 
                   6427: @section VIEW 21: View Size of Last Global
                   6428: @cindex VIEW commands/functions, 21, view size of last global
                   6429: 
                   6430: Allows the user to view the size of the last referenced global.
                   6431: 
                   6432: @section VIEW 22: Count VIEW 22 Aliases
                   6433: @cindex VIEW commands/functions, 22, count VIEW 22 aliases
                   6434: 
                   6435: Retrieves the number of VIEW 22 aliases in effect.
                   6436: 
                   6437: @section VIEW 23: View Contents of Input Buffer
                   6438: @cindex VIEW commands/functions, 23, input buffer contents
                   6439: 
                   6440: Retrieves the contents of the I/O input buffer.
                   6441: 
                   6442: @section VIEW 24: Maximum Number of Screen Rows
                   6443: @cindex VIEW commands/functions, 24, maximum number of screen rows
                   6444: 
                   6445: Retrieves the maximum number of screen rows supported in the current FreeM build.
                   6446: 
                   6447: @section VIEW 25: Maximum Number of Screen Columns
                   6448: @cindex VIEW commands/functions, 25, maximum number of screen columns
                   6449: 
                   6450: Retrieves the maximum number of screen columns supported in the current FreeM build.
                   6451: 
                   6452: @section VIEW 26: DO/FOR/XECUTE Stack Pointer
                   6453: @cindex VIEW commands/functions, 26, DO/FOR/XECUTE stack pointer
                   6454: 
                   6455: Retrieves the @code{DO}, @code{FOR}, and @code{XECUTE} stack pointer.
                   6456: 
                   6457: @section VIEW 27: DO/FOR/XECUTE Stack Pointer (On Error)
                   6458: @cindex VIEW commands/functions, 27, DO/FOR/XECUTE stack pointer, on error
                   6459: 
                   6460: Retrieves the @code{DO}, @code{FOR}, and @code{XECUTE} stack pointer (on error).
                   6461: 
                   6462: @section VIEW 29: Copy Symbol Table
                   6463: @cindex VIEW commands/functions, 29, copy symbol table
                   6464: 
                   6465: Copies the symbol table? We aren't currently aware of what this means.
                   6466: 
                   6467: @section VIEW 30: Inspect Arguments
                   6468: @cindex VIEW commands/functions, 30, inspect arguments
                   6469: 
                   6470: Retrieves the arguments passed to the @code{freem} executable.
                   6471: 
                   6472: @section VIEW 31: Count Environment Variables
                   6473: @cindex VIEW commands/functions, 31, count environment variables
                   6474: 
                   6475: Allows the user to inspect the number of variables in the process environment table.
                   6476: 
                   6477: @emph{Syntax}
                   6478: 
                   6479: @example
                   6480: WRITE $VIEW(31),!
                   6481: @end example
                   6482: 
                   6483: @node Implementation Limits
                   6484: @appendix Implementation Limits
                   6485: 
                   6486: @cindex limitations, memory
                   6487: @cindex maximum size, routine
                   6488: @cindex maximum size, global
                   6489: @cindex maximum size, string
                   6490: 
                   6491: @node US-ASCII Character Set
                   6492: @appendix US-ASCII Character Set
                   6493: 
                   6494: @multitable {Code} {Character} 
                   6495: @item Code @tab Character
                   6496: @item 000 @tab @code{<NUL>}
                   6497: @item 001 @tab @code{<SOH>}
                   6498: @item 002 @tab @code{<STX>}
                   6499: @item 003 @tab @code{<ETX>}
                   6500: @item 004 @tab @code{<EOT>}
                   6501: @item 005 @tab @code{<ENQ>}
                   6502: @item 006 @tab @code{<ACK>}
                   6503: @item 007 @tab @code{<BEL>}
                   6504: @item 008 @tab @code{<BS>}
                   6505: @item 009 @tab @code{<HT>}
                   6506: @item 010 @tab @code{<LF>}
                   6507: @item 011 @tab @code{<VT>}
                   6508: @item 012 @tab @code{<FF>}
                   6509: @item 013 @tab @code{<CR>}
                   6510: @item 014 @tab @code{<SO>}
                   6511: @item 015 @tab @code{<SI>}
                   6512: @item 016 @tab @code{<DLE>}
                   6513: @item 017 @tab @code{<DC1>}
                   6514: @item 018 @tab @code{<DC2>}
                   6515: @item 019 @tab @code{<DC3>}
                   6516: @item 020 @tab @code{<DC4>}
                   6517: @item 021 @tab @code{<NAK>}
                   6518: @item 022 @tab @code{<SYN>}
                   6519: @item 023 @tab @code{<ETB>}
                   6520: @item 024 @tab @code{<CAN>}
                   6521: @item 025 @tab @code{<EM>}
                   6522: @item 026 @tab @code{<SUB>}
                   6523: @item 027 @tab @code{<ESC>}
                   6524: @item 028 @tab @code{<FS>}
                   6525: @item 029 @tab @code{<GS>}
                   6526: @item 030 @tab @code{<RS>}
                   6527: @item 031 @tab @code{<US>}
                   6528: @item 032 @tab @code{<space>}
                   6529: @item 033 @tab !
                   6530: @item 034 @tab ``
                   6531: @item 035 @tab #
                   6532: 
                   6533: 
                   6534: @end multitable
                   6535: 
                   6536: @node FreeM Project Coding Standards
                   6537: @appendix FreeM Project Coding Standards
                   6538: 
                   6539: @section Module Headers
                   6540: @cindex coding standards, module headers
                   6541: 
1.4       snw      6542: Module headers should adhere to the following format (where @code{Dollar} should be replaced with a dollar sign):
1.1       snw      6543: 
                   6544: @verbatim
                   6545: /*
1.4       snw      6546:  *   DollarIdDollar
1.1       snw      6547:  *    Function prototypes, structs, and macros for FreeM
                   6548:  *    binding library
                   6549:  *
                   6550:  *  
1.28      snw      6551:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw      6552:  *    Copyright (C) 1998 MUG Deutschland
1.4       snw      6553:  *    Copyright (C) <Year> Coherent Logic Development LLC
                   6554:  *
                   6555:  *   This file is part of FreeM.
                   6556:  *
                   6557:  *   FreeM is free software: you can redistribute it and/or modify
                   6558:  *   it under the terms of the GNU Affero Public License as published by
                   6559:  *   the Free Software Foundation, either version 3 of the License, or
                   6560:  *   (at your option) any later version.
                   6561:  *
                   6562:  *   FreeM is distributed in the hope that it will be useful,
                   6563:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
                   6564:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                   6565:  *   GNU Affero Public License for more details.
                   6566:  *
                   6567:  *   You should have received a copy of the GNU Affero Public License
                   6568:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
                   6569:  *
                   6570:  *   DollarLogDollar
1.1       snw      6571:  *
1.4       snw      6572:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
                   6573:  * SPDX-License-Identifier: AGPL-3.0-or-later
1.1       snw      6574:  **/
                   6575: @end verbatim
                   6576: 
                   6577: @section Variable Naming
                   6578: @cindex coding standards, variable naming
                   6579: 
                   6580: Variables should be named in all lowercase letters, and words within them delimited by underscores, such as @code{my_useful_variable}. @code{PascalCase} and @code{camelCase} are not to be used in this codebase under any circumstances.
                   6581: 
                   6582: Constants defined via the C preprocessor should be in all uppercase letters, with words within them likewise delimited by underscores, such as:
                   6583: 
                   6584: @verbatim
                   6585: #define MY_USEFUL_CONSTANT 1
                   6586: @end verbatim
                   6587: 
                   6588: @section Indentation and General Layout
                   6589: @cindex coding standards, indentation
                   6590: @cindex coding standards, layout
                   6591: 
                   6592: 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.
                   6593: 
                   6594: This project follows a modified version of what is known as the Stroustrup indentation style.
                   6595: 
                   6596: @section Brace Placement (Functions)
                   6597: @cindex coding standards, brace placement, functions
                   6598: 
                   6599: 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.
                   6600: 
                   6601: Below is a correct example:
                   6602: 
                   6603: @verbatim
                   6604: int main(int argc, char **argv, char **envp)
                   6605: {
                   6606: 
                   6607: }
                   6608: @end verbatim
                   6609: 
                   6610: @section Brace Placement (if-for-while-do)
                   6611: @cindex coding standards, brace placement, if-for-while-do
                   6612: 
                   6613: The @code{if} keyword should be followed by one space, then the opening paren and conditional expression. We also use Stroustrup-style @code{else} blocks, rather than the K&R 'cuddled' @code{else}:
                   6614: 
                   6615: @verbatim
                   6616: if (x) {
                   6617: ...
                   6618: }
                   6619: else {
                   6620: ...
                   6621: }
                   6622: 
                   6623: while (1) {
                   6624: ...
                   6625: }
                   6626: 
                   6627: for (i = 1; i < 10; i++) {
                   6628: ...
                   6629: }
                   6630: 
                   6631: do {
                   6632: ...
                   6633: } while (x);
                   6634: @end verbatim
                   6635: 
                   6636: Single-statement if blocks should be isolated to a single line:
                   6637: 
                   6638: @verbatim
                   6639: if (x) stmt();
                   6640: @end verbatim
                   6641: 
                   6642: not:
                   6643: 
                   6644: @verbatim
                   6645: if (x)
                   6646:     stmt ();
                   6647: @end verbatim
                   6648: 
                   6649: Notice that there is a space between @code{if} and @code{(x)}, and also between @code{stmt} and @code{()}. This should be followed throughout the code.
                   6650: 
                   6651: If an @code{if} block has an @code{else if} or @code{else}, all parts of the construct must be bracketed, even if one or more of them contain only one statement:
                   6652: 
                   6653: @verbatim
                   6654: if (x) {
                   6655:     foo();
                   6656: }
                   6657: else if (y) {
                   6658:     bar();
                   6659: }
                   6660: else {
                   6661:     bas();
                   6662: }
                   6663: @end verbatim
                   6664: 
                   6665: @section Labels and goto
                   6666: @cindex coding standards, labels
                   6667: @cindex coding standards, goto
                   6668: 
                   6669: Labels must begin in column 1, and have two lines of vertical space above and one beneath.
                   6670: 
                   6671: @section Preprocessor Conditionals
                   6672: @section coding standards, preprocessor conditionals
                   6673: 
                   6674: I have struggled with this, but have settled upon the standard practice of keeping them in column 1.
                   6675: 
                   6676: @section Overall Program Spacing
                   6677: @cindex coding standards, spacing of programs
                   6678: 
                   6679: @itemize @bullet
                   6680: @item
                   6681: Variable declarations fall immediately beneath the opening curly brace, and should initialize the variable right there whenever initialization is used.
                   6682: 
                   6683: @item
                   6684: One line between the last variable declaration and the first line of real code.
                   6685: 
                   6686: @item
                   6687: The @code{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.
                   6688: 
                   6689: @item
                   6690: 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.
                   6691: @end itemize
                   6692: 
                   6693: @section The switch() Statement
                   6694: @cindex coding standards, switch()
                   6695: 
                   6696: We indent @code{case} one level beneath @code{switch()}, and the code within each @code{case} beneath the @code{case}. Each @code{case} should have one line of vertical whitespace above it:
                   6697: 
                   6698: @verbatim
                   6699: switch(foo) {
                   6700: 
                   6701:     case some_const:
                   6702:         foo();
                   6703: 
                   6704:         break;
                   6705: 
                   6706:     case some_other_const:
                   6707:         bar();
                   6708: 
                   6709:         break;     
                   6710: 
                   6711:     default:
                   6712:         exit(1);
                   6713: 
                   6714:         break;
                   6715: }
                   6716: @end verbatim
                   6717: 
                   6718: @section Comments
                   6719: @cindex coding standards, comments
                   6720: 
                   6721: We use C-style comments (@code{/* comment */}) exclusively, even on single-line comments. C++ comments (@code{// comment}) are not permitted.
                   6722: 
                   6723: @node Index
                   6724: @unnumbered Index
                   6725: 
                   6726: @printindex cp
                   6727: 
                   6728: @bye

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>