File:  [Coherent Logic Development] / freem / doc / freem.texi
Revision 1.31: download - view: text, annotated - select for diffs
Sat Apr 19 01:05:56 2025 UTC (6 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Further work on FreeM Manual

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

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