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