Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50472/scan.rnd
There are no other files named scan.rnd in the archive.
.! to get the DEC version of this manual, use the
.! /VARIANT:DEC switch in the RUNOFF command screen
.flag index
.AUTOPAR
.DATE
.flag bold $
.autosubtitle
##########
.SPACING 1
.NONUMBER
.ski8
.CENTER
^$SCAN USER'S MANUAL\$
.ski7
.CENTER
Reed Powell
.center
Digital Equipment Corp.
.center
Western Region Software Operations Group
.center
Santa Clara, California
.SKIP 1
.center
11-June-79
.skip 3
.center
^$EDITION:  2.5\$
.if DEC
-DEC
.ENDIF DEC
.IFNOT DEC
-OLS
.ENDIF DEC
.ski6
.LM10
.RM 50
This manual reflects the status of SCAN, Version 
.if DEC
7(541)
.endif DEC
.ifnot DEC
7(11,541)
This is a modified version of SCAN 7(541), which
contains a number of additions, improvements and corrections installed at On-Line Systems, Inc. ("OLS").  While it
reflects the overall operation of any SCAN release from 7(541) upwards, no guarantee is made as to the
applicability or correctness of statements made herein.
.endif DEC
.SKIP 2
^$
Ownership rights to the contents remain with
On-Line Systems, Inc., Pittsburgh, Pa.
\$
.page
.rm60
.lm 1
.autopar
.ski4
.cenTER
^$Table of Contents\$
.LIST
.LE
Introduction
.LE
Routine Call Definitions
.LE
The Command Scanners (Overview)
.LE
Defining Switches - "SWTCHS" Macro
.LE
The "DM" and "KEYS" Macros
.LE
Defining the "STORAGE" Field
.le
Default Value Handling
.LE
File-Spec Scanning
.LE
ISCAN - Scanner Initialization
.LE
TSCAN - The Traditional Scanner
.LE
OSCAN - Options File Scanning
.LE
VSCAN - The Verb Form Scanner
.LE
PSCAN - The Partial Mode Scanner
.LE
Accessing SCAN
.le
Example of Using SCAN
.le
Using the Miscellaneous Routines
.le
Appendices:
.skip 1
.LIST 0,'o'
.LE
Notes on using SCAN
.LE
Notes on using WILD
.ifnot DEC
.LE
DEC/OLS differences in SCAN and WILD
.endif DEC
.LE
SCNMAC
.LE
_$SCNDC
.LE
SWTCHS, DOSCAN, DM _& KEYS Examples
.le
LIST OF CUSPS _& THE SCANNERS THEY USE
.END LIST
.skip 1
.le
Index
.end list
.number
.CHAPTER INTRODUCTION
.LM1
.RM 65
.ski4
.ski6
.hl1 INTRODUCTION
 SCAN is a library of well-written routines of general applicability to a wide variety of user programs.  Included in SCAN
are: command scanners; input and output routines for file specifications, numbers, dates, strings and characters;
.ifnot DEC
space allocation;
.endif DEC
data management; universal date-time conversions; register saving; and indirect-file handling.
All routines are written to be virtually independent of the main program's register conventions.  Only two constraints
exist:
 
.LM 3
.LIST ,'o'
.LE
AC17 must be a stack pointer, with a stack depth at call time of at least 15.
.LE
AC1 and AC7 are used to pass arguments, and (when applicable), return values.
.END LIST
.LM 1
.SKI 1
All routines will preserve any registers which they do not return a value in.
 
 The default character input and output method is via TTCALLs, but the user is free to specify the address of his own
routine if he so desires.  For character input, the same rule applies, but the user must always call an initialization
routine as well.  The routines described in chapter two will be those which are the most generally useful, and fall into the
.noautopar
following groupings:
.SKI 3
	Initialization
.BREAK
	Register Saving
.BREAK
.ifnot DEC
	Space Allocation
.BREAK
.endif DEC
	Output Routines - all
.BREAK
	Input Routines - numbers, dates, file-specs, and words
.SKIP 3
.TEST PAGE 20
.BREAK
.index register mnemonics
The register mnemonics used will be those of SCAN, which are:
.SKIP 2
       T1 - T4:  1-4   ("Temporaries")
.BREAK
P1 - P4:  5-10  ("Permanents")
.BREAK
######P:  17    ("Stack Pointer")
.BREAK
.autopar
.SKIP 2
 All calls are via a PUSHJ, and return at the call+1 or call+2.
.ifnot DEC
SCAN is loaded in library search mode from (70001,1).

(See the section on "Accessing SCAN and its Macros".)
.endif DEC
.CHAPTER ROUTINE CALL DEFINITIONS
.ski1
.hl1 >INITIALIZATION
 
.LM15
.skip 1
.INDENT -9
#.TYOCH -
.index .TYOCH
Use the address in T1 as the typeout routine.  Returns the previous routine's address (if any) in T1.
.skip 1
.INDENT -9
#.ISCAN -
.INDEX .ISCAN
Initialize for input.  T1 is a pointer to an argument block:
.noautopar
.SKIP 1
   T1/ LENGTH,, BLOCK
.SKIP 1
  BLOCK: Z
.BREAK
   +1: Z
.BREAK
   +2: INPUT ROUTINE,,OUTPUT ROUTINE
.BREAK
   +3: Z
.BREAK
   +4: Z
.BREAK
   +5: Z
.BREAK
.SKIP 1
If "Input Routine" or "Output Routine"
(or both) is zero, then TTCALL I/O (e.g.: INCHWL or OUTCHR)
is used.  The chapter on ".ISCAN"  describes the meanings and
usages of the other words in the argument blocks.
.ifnot DEC
.ski4
-----------------------------------------------
.skip 1
.lm 10
.indent -10
NOTE:  Those routine descriptions marked with an asterisk (*)
in the outer left hand margin are not a part of the standard
Digital supplied SCAN.  These routines are peculiar to the modified
version of SCAN for which this manual was written.
.endif DEC
.lm1
.autopar
.break;.subttl Register Saving; Allocation; Text Output
.page
.LM1
.hl1 >REGISTER-SAVING
.skip 1
.LM6
#.SAVE1 - Save P1
.INDEX REGISTER SAVING
.INDEX .SAVEX
.INDEX .POPJ
.INDEX .POPJ1
.INDEX .POP4T
.INDEX .PSH4T
.BREAK
#.SAVE2 - Save P1-P2
.BREAK
#.SAVE3 - Save P1-P3
.BREAK
#.SAVE4 - Save P1-P4
.break
.ifnot DEC
#$*.SAV1T - Save T4
.INDEX .SAVXT
.break
#$*.SAV2T - Save T3-T4
.break
#$*.SAV3T - Save T2-T4
.break
#$*.SAVET - Save T1-T4
.BREAK
.endif DEC
#.POPJ#  - Non-skip return (do a POPJ)
.break
#.POPJ1 - Skip return
.BREAK
#.PSH4T - Stack T1-T4
.BREAK
#.POP4T - Unstack T1-T4
.BREAK
.ski1
.LM1
.TEST PAGE 2
.break
All of the .SAVxx routines automatically restore the registers on a skip or non-skip return from the routine which called
the .SAVxx routine.
.ski4
.LM1
.ifnot DEC
.hl1 SPACE;ALLOCATION
.INDEX SPACE ALLOCATION
.skip 1
.LM15
.INDENT -9
$*.GTWDS -
.INDEX .GTWDS
Allocate (upwards from .JBFF) the number of words in T1.  T1 is returned with the address, if the allocation was
successful, of the first word.  The allocated area will be zeroed.  On a failure, T1 will contain the negative number of
words available.
.ski2
.endif DEC
.LM1
.test page 15
.break
.index output routines - text
.hl1 OUTPUT ROUTINES - Text
.skip 1
.LM15
.INDENT -9
#.TSIXN -
.INDEX .TSIXN
Type T1 in SIXBIT.
.INDENT -9
#.TSTRG -
.INDEX .TSTRG
Type ASCIZ string which T1 points to.
.INDENT -9
#.TXWWW -
.INDEX .TXWWW
Type a wild octal word; T1 contains the word, T2 contains the mask.
.INDENT -9
#.TMOHW -
.INDEX .TMOHW
Type a wild octal half word; the word is in LH of T1, the mask is in RH.
.ski2
.break;.subttl Output:  Date/Time, Numbers, File-Specs
.test page 14
.break
.LM1
.index date/time
.INDEX OUTPUT ROUTINES - Date/Time
.hl1 OUTPUT ROUTINES - Date/Time
.skip 1
.LM15
.INDENT -9
#.TDTTM -
.INDEX .TDTTM
Type the date and time which is in T1; the argument is in the Universal Date/Time format.
.INDENT -9
#.TDATE -
.INDEX .TDATE
Type the date which is in T1; the argument is in the standard DEC format (a la DATE UUO).
.INDENT -9
#.TDATN -
.INDEX .TDATN
Type the current date.
.INDENT -9
#.TTIME -
.INDEX .TTIME
Type the time which is in T1; the argument is the number of milliseconds past midnight (a la MSTIME UUO).
.INDENT -9
#.TTIMN -
.INDEX .TTIMN
Type the current time.
.ski2
.LM1
.TEST PAGE 25
.BREAK
.index numeric output
.index OUTPUT ROUTINES - Numeric Output
.hl1 OUTPUT ROUTINES - Numbers
.skip 1
.LM15
.INDENT -9
#.TDECW -
.INDEX .TDECW
Type T1 as a decimal number.
.INDENT -9
#.TDEC2 -
.INDEX .TDEC2
Type T1 as a decimal number with at least two positions; fill character is in T2.
.INDENT -9
#.TOCTW -
.INDEX .TOCTW
Type T1 as an octal number.
.INDENT -9
#.TRDXW -
.INDEX .TRDXW
Type T1 in the radix which is in T3.
.INDENT -9
#.TXWDW -
.INDEX .TXWDW
Type T1 as an octal number, in XWD format (LH,,RH)
.INDENT -9
#.TVERW -
.INDEX .TVERW
.INDEX VERSION NUMBERS - TYPING
Type T1 as a standard DEC version number.
.INDENT -9
#.TCORW -
.INDEX .TCORW
.INDEX CORE SIZES - TYPING
.INDEX OUTPUT ROUTINES - CORE SIZE
Type T1 as a core size, in P, K, or Words.
.INDENT -9
#.TBLOK -
.INDEX .TBLOK
.INDEX FILE SIZES - TYPING
.INDEX OUTPUT ROUTINES - FILE SIZE
Type T1 as a file size, in Blocks or Words.
.INDENT -9
#.TPPNW -
.INDEX .TPPNW
.INDEX PPNS - TYPING
.INDEX TYPING PPNS
.INDEX OUTPUT ROUTINES - PPN
Type T1 as a PPN.
.ski2
.LM1
.index file specification output
.index OUTPUT ROUTINES - File Specifications
.hl1 OUTPUT ROUTINES - File Specifications
.skip 1
.LM15
.INDENT -9
#.TOLEB -
.INDEX .TOLEB
.INDEX OUTPUT ROUTINES - OPEN/LOOKUP BLOCK
.INDEX TYPING OPEN/LOOKUP BLOCKS
.INDEX OPEN/LOOKUP BLOCKS - TYPING
.INDEX LOOKUP/OPEN BLOCKS - TYPING
.INDEX ENTER/LOOKUP/OPEN BLOCKS - TYPING
Type a file-spec. T1 points to an OPEN UUO block; T2 points to an extended LOOKUP or ENTER UUO block of at least
four words.
.ski2
.break;.subttl Output:  Character
.TEST PAGE 30
.BREAK
.LM1
.hl1 OUTPUT ROUTINES - Character
.index character output
.skip 1
.LM15
.INDENT -9
#.TCHAR -
.INDEX .TCHAR
Type T1 as an ASCII character.
.INDENT -9
#.TFCHR -
.INDEX .TFCHR
Type T2, using mnemonics and abbreviations for non-printing characters, and preceeding lower-case characters with an apostrophe.
.INDENT -9
#.TCRLF -
.INDEX .TCRLF
.indent -9;#.TSPAC -
.INDEX .TSPAC
.indent -9;#.TTABC -
.INDEX .TTABC
Type a horizonal tab.
.indent -9;#.TCOLN - 
.INDEX .TCOLN
.index .TCOLN
Type a colon.
.indent -9;#.TASTR -
.INDEX .TASTR
Type an asterisk.
.indent -9;#.TRBRK -
.INDEX .TRBRK
Type a right bracket character.
.indent -9;#.TCOMA -
.INDEX .TCOMA
Type a comma.
.ifnot DEC
.INDENT -9;$*.T2CRL -
.INDEX .T2CRL
.INDENT -9;$*.T4CRL -
.INDEX .T4CRL
Type 1, 2 or 4 CRLF's, respectively
.INDENT -9;$*.T2SPC -
.INDEX .T2SPC
.INDENT -9;$*.T4SPC -
.INDEX .T4SPC
Type 1, 2, or 4 spaces, respectively
.indent -9;$*.TPLUS -
.INDEX .TPLUS
Type a plus sign.
.indent -9;$*.TSLSH -
.INDEX .TSLSH
Type a slash character.
.indent -9;$*.TAPOS -
.INDEX .TAPOS
Type an apostrophe.
.indent -9;$*.TCART -
.INDEX .TCART
Type a caret (up arrow on some printers).
.indent -9;$*.TRPAR -
.INDEX .TRPAR
Type a right parenthesis.
.indent -9;$*.TRANG -
.INDEX .TRANG
Type a right angle bracket
.indent -9;$*.TLPAR -
.INDEX .TLPAR
Type a left parenthesis.
.indent -9;$*.TLBRK -
.INDEX .TLBRK
Type a left bracket.
.INDENT -9;$*.TLANG -
.INDEX .TLANG
Type a left angle bracket.
.INDENT -9;$*.TAMPR -
.INDEX .TAMPR
Type an ampersand.
.INDENT -9;$*.TAROW -
.INDEX .TAROW
Type a left arrow (underscore on some printers).
.indent -9;$*.TATSI -
.INDEX .TATSI
Type an at-cost sign.
.indent -9;$*.TDASH -
.INDEX .TDASH
Type a dash.
.indent -9;$*.TDOLR -
.INDEX .TDOLR
Type a dollar sign.
.indent -9;$*.TEQUL -
.INDEX .TEQUL
Type an equal sign.
.indent -9;$*.TEXCL -
.INDEX .TEXCL
Type an exclamation mark.
.indent -9;$*.TPCNT -
.INDEX .TPCNT
Type a per cent sign.
.indent -9;$*.TSEMI -
.INDEX .TSEMI
Type a semi-colon.
.indent -9;$*.TQUOT -
.INDEX .TQUOT
Type a double-quote mark.
.indent -9;$*.THASH -
.INDEX .THASH
Type a hash mark ("_#").
.indent -9;$*.TBKSL -
.INDEX .TBKSL
Type a back-slash character ("_\").
.endif DEC
.LM1
.TEST PAGE 20
.break
.hl1 INPUT ROUTINES - Introduction
 The input routines will normally leave their result in accumulator
"P3" - which they use under the alias "N".  Single character input routines
will use "P4", under the alias "C".
 Most routine descriptions given below will list two names; the second
one will often be the same as the first but with the last character
of the name changed to "C".  The second routine entry point
is used when the next character in the input stream is already in
accumulator "CH" ("P4"), while the first routine entry point
is used when the next character in the stream has not yet been
input.
 This ability to already have the next input character waiting is
used in conjunction with the so called "re-eat" facility of SCAN, which
allows a program to look-ahead one character.  The routine ".REEAT"
is used to perform this, and is described later in this chapter in the
section "MISCELLANEOUS ROUTINES."
 More information on this is included in the chapter on USING THE
MISCELLANEOUS ROUTINES.
.break;.subttl Input:  String, Numeric, Date/Time
.page
.break
.hl1 INPUT ROUTINES  -  String and Numeric
.index INPUT ROUTINES
.index INPUT ROUTINES - String and Numeric
.skip 1
.LM23
.INDENT -17
#.SIXSW, .SIXSC -
.INDEX .SIXSW
.INDEX INPUTTING SIXBIT WORDS
.INDEX INPUTTING WORDS/STRINGS - SIXBIT
.INDEX .SIXSC
Input a SIXBIT word into P3.
.INDENT -17
#.OCTNW, .OCTNC -
.INDEX .OCTNW
.INDEX .OCTNC
.INDEX INPUTTING OCTAL NUMBERS
.INDEX INPUTTING NUMBERS - OCTAL
Input an octal number into P3.
.INDENT -17
#.DECNW, .DECNC -
.INDEX .DECNW
.INDEX .DECNC
.INDEX INPUTTING DECIMAL NUMBERS
.INDEX INPUTTING NUMBERS - DECIMAL
.INDEX SUFFIXES - DECIMAL _& OCTAL INPUT
Input a decimal number into P3.
.skip 1
Optional suffixes for decimal and octal input are: K, M and G, for the base raised to the third, sixth, and nineth power,
respectively.
.skip 1
.INDENT -17
#.NAMEW, .NAMEC -
.INDEX .NAMEW
.INDEX .NAMEC
.INDEX INPUTTING SIXBIT WORDS - WILD
.INDEX INPUTTING WORDS/STRINGS - WILD SIXBIT
Input a possibly wild SIXBIT word; word is in P3, mask is in "MASK".
.skip 1
.indent -17;#.ASCQW, .ASCQC -
.INDEX .ASCQW
.INDEX .ASQCQ
.INDEX INPUTTING ASCII STRINGS
.INDEX INPUTTING WORDS/STRINGS - ASCII
Input a possibly quoted ASCII string.  The string will be
input into the area (inside SCAN) beginning at the global
symbol ".NMUL", and extending no further than the symbol ".NMUE".
Input terminates at the first non-alphanumeric character.  Any characters
within the string being typed, but which cannot be fit into the
buffer, is lost.  Since the symbols are global, they are
accessable from the calling program, which should BLT them to a safe
place.
.skip 1
.indent -17;#.SIXQW, .SIXQC -
.INDEX .SIXQW
.INDEX .SIXQC
.INDEX INPUTTING SIXBIT STRINGS
.INDEX INPUTTING WORDS/STRINGS - SIXBIT
This functions exactly as does .ASCQW/.ASCQC above, except that
the characters are stored in SIXBIT rather than ASCII.
.skip 1
.indent -17;#.SIXMW, .SIXMC -
.INDEX .SIXMW
.INDEX INPUTTING SIXBIT STRINGS
.INDEX INPUTTING WORDS/STRINGS - SIXBIT
.INDEX .SIXMC
This functions exactly as does .SIXQW/.SIXQC above, except that
the input string cannot be quoted.
.skip 3
.break
.lm1
.hl1 INPUT ROUTINES  -  Date/Time
.lm23
.index Date/Time
.index INPUT ROUTINES - Date/Time
.skip 2
.break
[More information on this subject is contained in the later chapter
on USING THE MISCELLANEOUS ROUTINES]
.SKIP 1
.INDENT -17
#.DATIM, .DATIC -
.INDEX .DATIM
.INDEX .DATIC
.INDEX INPUTTING DATES - UNIVERSAL FORMAT
.INDEX INPUTTING DATES - GENERAL
.INDEX UNVERSAL DATE/TIME INPUT
Input date-time into P3, storing it in universal format.
.INDENT -17
#.DATIP, .DATIQ -
.INDEX .DATIP
.INDEX .DATIQ
.INDEX INPUTTING DATES - PAST
Input a date-time in the past into P3, storing it in universal format.
.INDENT -17
#.DATIF, .DATIG -
.INDEX .DATIF
.INDEX .DATIG
.INDEX INPUTTING DATES - FUTURE
Input a date-time in the future into P3, storing it in universal format.
.skip 1
.indent -17
Legal date-time formats, examples and explanations are:
.PAGE
.LIT
	FORMAT		EXAMPLE		EXPLANATION

DATE-SPEC:
	day		WED		WEDNESDAY
	day offset	123D		123 days
					ago from now
	MM-DD		6-12		Jun. 12
	MM-DD-Y		6-12-6		Jun. 12, 1976
	MMM-DD-YY	JUN-12-76	June 12, 1976
	DD-MMM-YYYY	12-JUN-1976	June 12, 1976
	Mnemonic	YESTERDAY
			TOMORROW
			TODAY

TIME-SPEC:
	HH		12		noon
	HH:MM		13:02		2 past 1 PM
	HH:MM:SS	1:02:37		37 secs past
	        	        	1:02 AM
	mnemonic	NOON
			LOGIN


DATE-TIME:
	date-spec:time-spec	JUN-12-76:13:02:37

.end lit
.lm 1
.hl1 INPUT ROUTINES  -  Version Number
.INDEX VERSION NUMBERS - INPUTTING
.index INPUT ROUTINES - Version Numbers
.skip 2
.lm 23
.INDENT -17
#.VERSW, .VERSC -
.index .versw
.index .versc
.index inputting version numbers
.index version numbers - inputting
Input a version number into P3.
Version number format is:
.SKI 2
NNMM(EE) where:
.skip 1
.indent 5;NN is the major version, blank to 511
.indent 5;MM is the minor version, blank to ZZ
.indent 5;(EE) is the edit number, 
.indent 7;blank to 202,143
.skip 3
.test page 15
.lm 1
.hl1 INPUT ROUTINES  -  Core _& File Sizes
.index INPUT ROUTINES - Core _& File Sizes
.skip 2
.lm 23
.INDENT -17
#.COREW, .COREC -
.index .corew
.index .corec
.index inputting core sizes
.index core sizes - inputting
Input a core size in words,
pages, or K; suffixes are:  W (default), P and K, respectively.
Returns size, in words, in P3.
.INDENT -17
#.BLOKW, .BLOKC -
.index .blokw
.index .blokc
.index inputting file sizes
.index file sizes - inputting
Input a file size in words or blocks; suffixes are:  W (default) or B.
Returns size in words in P3.
.lm 1
.skip 3
.test page 10
.hl1 INPUT ROUTINES -  Characters
.index INPUT ROUTINES - Characters
.index Character Input
.SKIP 2
.LM15
.INDENT -9
#.TICAN -
.INDEX .TICAN
.INDEX CHARACTER CHECKING
Check for an alphanumeric character in P4.  Non-skips if not alphanumeric, skips if it is.
.INDENT -9
#.TIMUC -
Convert character in P4 to upper case, if it is in lower case.
.INDENT -9
#.TIAUC -
Input a character into P4, handling lower case, altmodes and all compressions.
.INDENT -9
#.TIALT -
Input a character, handling altmodes and space compression, into P4.
.indent -9
#.TIGET -
Gets a character into P4, with no equivalencing.
.skip 2
.break;.subttl Input:  Character, File Specifications
.TEST PAGE 9
.break
For .TIAUC and .TIALT, P4 is returned in the following format:
.test page 20
.break
 
.SKI 1
1-177:	actual character
.BREAK
####0:	end-of-line character
.break
###-1:	altmode
.BREAK
###-2:	end-of-file
.break
########(Control Z or EOF on indirect file)
.BREAK
.skip 1
#The following are Guide Words (pseudo characters):
.skip 1
.lit
 4000:	'AND'
 4001:	'OR'
 4002:	'NOT'
 4003:	'TO'
 4004:	'FROM'
 4005:	'INPUT'
 4006:	'OUTPUT'
 4007:	'SOURCE'
 4010:	'LIST'
 4011:	'OBJECT'
.END LIT
.SKIP 1
 See "SYNTAX REPRESENTATIONS" in Chapter 8.  Also refer to Appendix
D - "SCNMAC."
.index Guide Words
.SKI 3
.test page 10
.lm 1
.hl1 INPUT ROUTINE  -  File Specifications
.index File Specification Input
.INDEX INPUT ROUTINES - File Specifications
.skip 2
.lm 15
 
.INDENT -9
#.FILIN -
.INDEX .FILIN
.INDEX INPUTTING FILE SPECIFICATONS
.INDEX FILE SPECIFICATION INPUTTING
Input a file specification.  Details on its usage is the subject of a later chapter in this document.
.break;.subttl MISC:  /RUN, Table Searching, Random Numbers, Date conversion
.page
.index MISCELLANEOUS ROUTINES
.LM1
.hl1 MISCELLANEOUS ROUTINES
.skip 1
.LM15
.INDENT -9
#.RUNCM -
.INDEX .RUNCM
.INDEX RUN UUO
.INDEX /RUN SWITCH PROCESSING
.INDEX CHAINING EXECUTION
Process a /RUN  specification, if any has been encountered.  No arguments are possible; returns only if no /RUN was ever
seen on the line, or if the RUN UUO failed.  Usually called right before normal program termination code.
More on this routine in included in a later chapter on USING THE MISCELLANEOUS
ROUTINES.
.skip 2
.INDENT -9
#.MKPJN -
.INDEX .MKPJN
.INDEX CCL JOB NUMBER
Make a CCL job number.  Call with the job number (or whatever) in T1.  Returns with SIXBIT form of argument in (RH) of
T1.
More information is in a later chapter on USING THE MISCELLANEOUS ROUTINES.
.INDEX USING THE MISCELLANEOUS ROUTINES
.skip 2
.TEST PAGE 8
.break
.INDENT -9
#.LKNAM -
.index .LKNAM
.INDEX TABLE SEARCHING
Do a table search for an exact or abbreviated match.  Call with SIXBIT value in T2, and a pointer in T1 of the form:
.ski 1
.cenTER
IOWD length, table-address
.skip 1
 
Skip-returns if a match was found, with (RH) of T1 pointing to the match, and (LH) of T1
zero if it was abbreviated, or negative if an exact match.  Non-skip returns if unsuccessful, with T1
negative if no match was found, or positive if multiple matches were found.
A later chapter (USING THE MISCELLANEOUS ROUTINES) covers this routine
in greater detail.
.index USING THE MISCELLANEOUS ROUTINES.
.skip 2
.ifnot DEC
.INDENT -9
$*.RAND  -
.index .rand
.index random number generator
Generate a random number between 0 and 2$*$*18-1, storing it in T1.
 
.INDENT -9
$*.RANDM -
.index .randm
.index RANDOM NUMBER GENERATOR
Same as .RAND, but on call T1 contains the upper bound on the result.  Method used is "middle-squares."
.skip 2
.endif DEC
[More information on the following routines for date and time conversion
is included in a later chapter: USING THE MISCELLANEOUS ROUTINES]
.skip 1
.INDENT -9
#.CNTDT -
.INDEX .CNTDT
.INDEX DATE CONVERSION ROUTINES
.INDEX UNIVERSAL DATE/TIME - CONVERSION
Convert universal date/times to DEC formats.  Call with universal form in T1, returns with DEC date in T2, and MS in T1.
 
.INDENT -9
#.GTNOW -
.INDEX .GTNOW
.INDEX UNIVERSAL DATE/TIME - CURRENT
Get current date and time, in universal format, into T1.
 
.INDENT -9
#.CNVDT -
.INDEX .CNVDT
.INDEX DATE CONVERSION ROUTINES
.INDEX DEC DATE/TIME - CONVERSION
Convert DEC format date/time to universal format.  Call with time in T1, stored as the number of milliseconds past midnight (MSTIME UUO).
The date is in T2, stored in the standard DEC format (DATE UUO). Returns universal form
in T1 (or -1 if date was beyond September 27, 2217).  Note that "Day 0" was a Wednesday, and so (T1)/7 gives a day of
week index, with Wednesday being 0.
.skip 2
.break;.subttl MISC:  Scan-Block Conversion, Input Back-Spacing
.PAGE
.INDENT -9
#.STOPB -
.INDEX .STOPB
.INDEX SCAN BLOCK CONVERSION
.INDEX SCAN BLOCKS
.INDEX CONVERSION - SCAN BLOCKS
Convert a "scan-block" (see the later section on "FILE-SPEC SCANNING") to OPEN and extended LOOKUP/ENTER blocks.
Call with:
 
.LM18
.SKI 1
T1/ length,,address of scan-block
.BREAK
T2/ ######,,address of OPEN block
.BREAK
T3/ length,,address of LOOKUP block
.BREAK
T4/ ######,,address of PATH block (9 words)
.BREAK
.SKI 1
.LM15
.TEST PAGE 3
.break
Returns non-skip (error) if any wild-cards were seen in the scan-block; otherwise it skip-returns.
.skip 2
.TEST PAGE 3
.break
.INDENT -9
#.REEAT -
.INDEX .REEAT
.INDEX CHARACTER INPUT
.INDEX INPUT ROUTINES - CHARACTER
.INDEX CHARATER INPUT - POSITIONING
.INDEX INPUT LINE POSITIONING
Cause the contents of P4 to be the next character to be read.  P4 will normally contain the current character.  Call
is simply
 
.LM18
.SKI 1
MOVEI P4, char
.BREAK
PUSHT P,.REEAT##
.BREAK
 
.SKIP 1
.lm15
More information on this routine, and the general concept of positioning
input from the command line, is covered in a later chapter on USING THE
MISCELLANEOUS ROUTINES.
.INDEX USING THE MISCELLANEOUS ROUTINES
.SKI 2
.indent -9
#.CLRBF -
.INDEX .CLRBF
.INDEX INPUT ROUTINES - CLEARING INPUT BUFFERS
.INDEX CLEARING INPUT BUFFERS
This routine will clear any type ahead in the input stream.
No arguments are passed, no values returned, and control
always comes to the calling point +1.
.skip 1
.indent -9
#.GTWRD -
.INDEX .GTWRD
.INDEX MANIPULATING LISTS OF DATA
Get a word from a list.  Call with:
.skip 1
.lm20
T1/ table address
.break
T2/ length of table
.skip 1
.lm 15
On return (always to Call +1), the values are:
.skip 1
.lm20
T1/ incremented by 1
.break
T2/ decremented by 1
.break
T3/ data from list, or 0 if at end
.skip 1
.lm 15
This routine is covered in greater detail, along with the following routine
(.PTWRD), in a later chapter on USING THE MISCELLANEOUS ROUTINES.
.INDEX USING THE MISCELLANEOUS ROUTINES
.lm 15
.indent -9
#.PTWRD - 
.INDEX .PTWRD
.INDEX MANIPULATING LISTS OF DATA
Put a word into a list.  This is meant to be used along
with .GTWRD, above.  Control always returns to the call
+1 location.  Calling sequence is:
.test page 10
.skip 1
.lm 20
T1/ table address
.break
T2/ maximum table length
.break
T3/ data to be stored
.break
PUSHJ P,.PTWRD_#_#
.BREAK
T1/ incremented by 1
.break
T2/ decremented by 1
.break
T3/ old data from location stored into
.skip 2
.lm 15
.TEST PAGE 10
.indent -9
#.MKMSK -
.INDEX .MKMSK
.INDEX MASKS
.INDEX SIXBIT MASKS
This routine makes a mask for its argument word.  The argument
must be SIXBIT data.  The mask contains 1s  where the argument
had non-blanks. Calling sequence is:
.skip 1
.lm20
MOVE T3,argument
.break
PUSHJ P,.MKMSK
#-always returns here-
.break
T1/ mask for argument
.SKIP 1
.lm 15
More information on this routine is in the chapter USING THE MISCELLANEOUS ROUTINES.
.INDEX USING THE MISCELLANEOUS ROUTINES.
.skip 2
.lm 15
.indent -9
#.TDIRB -
.INDEX .TDIRB
.INDEX TYPING DIRECTORY INFORMATION
.INDEX TYPING LOOKUP/ENTER BLOCKS
.INDEX TYPING SCAN BLOCKS
.INDEX TYPING PATH BLOCKS
.INDEX SCAN BLOCKS
.INDEX LOOKUP/ENTER BLOCKS
.INDEX ENTER/LOOKUP BLOCKS
This routine is used to type out
directory blocks.  Three formats are accepted:  1) Extended
LOOKUP/ENTER blocks; 2) PATH blocks; and 3) "bi-words", which
is an internal SCAN format.
The calling sequence is:
.skip 1
.lm 20
HRLI T1,code
.break
HRRI T1,address
.BREAK
PUSHJ P,.TDIRB_#_#
.BREAK
#-always returns here-
.skip 1
where "code" is one of the following:
.skip 1
1 if (RH) is address of LOOKUP/ENTER block
.break
2 if (RH) is a PATH block address
.break
3 if (RH) is address of "bi-words"
.SKIP 1
.lm 15
More information on .TDIRB is in the chapter USING THE MISCELLANEOUS ROUTINES.
.INDEX USING THE MISCELLANEOUS ROUTINES
.skip 2
.lm 15
.indent -9
#.ISLGI -
.INDEX .ISLGI
.INDEX TESTING FOR LOGGED-IN JOBS
This routine is used to test to determine if the calling
job is logged in.  No argument is passed.  The value returned
is:
.skip 1
.lm 20
PUSHJ P,.ISLGI_#_#
.BREAK
#-here with T1=-1 if not logged in, or
.break
############T1=1 if indeterminate
.break
#-here if logged in (skip ret)
.lm 1
.autopar
.CHAPTER THE COMMAND SCANNERS
.flag capital
.lm1
.break;.subttl TSCAN, OSCAN, _& VSCAN
.hl1 INTRODUCTION
 This chapter will discuss the types of command scanners provided by
<scan.  The actual details of usage are covered separately in
later chapters on each scanner.  The purpose of this chapter is
to present the concepts of command scanners and switch types
which are relevant to determining which scanner is best for
various applications.
.index command scanners
.HL1 OVERVIEW OF THE 4 SCANNERS
 Within SCAN there are four basic Command 
Scanning routines, and an initialization routine.  The four scanners all accept
the same switch formats; their only differences lie in the structure of the command line itself.  The scanners are:
.SKI 1
.hl2 >TSCAN
.break
 This is the so-called "Traditional Scanner."  Command lines are of the form:
.skip 1
.indent 21;OUTPUT = INPUT
.BREAK
.indent 21;OUTPUT = INPUT,INPUT, ...
.BREAK
.indent 21;#####or
.BREAK
.indent 21;INPUT
.ski 1
Users of this syntax are PIP and DIRECT.
.SKIP 1
.hl2 >VSCAN
.break
 This is the "Verb Form Scanner."  Command lines look like:
.SKI 1
.indent 21;COMMAND-WORD /SWITCH/SWITCH
.BREAK
.indent 21;COMMAND-WORD /SWITCH/SWITCH FILE-SPEC
.BREAK
.indent 21;#####or
.BREAK
.indent 21;COMMAND-WORD
.skip 1
DUMP and BACKUP programs are users of this format.
.SKI 1
.hl2 >OSCAN
.break
 This is the "Option File Scanner."  This scans the options-file SWITCH.INI for entries of the form:
.SKI 1
.indent 21;NAME /SWITCH/SWITCH
.BREAK
.indent 21;#####or
.BREAK
.indent 21;NAME:OPTION /SWITCH/SWITCH
.skip 1
.SKIP 1
Users of this feature include LOGIN, DIRECT, BACKUP, SOS, and ALKFIL.
.skip 1
.hl2 >PSCAN
 PSCAN
is the "Partial Mode" Scanner.
Commands are of the <tscan style, but only part of the line is processed
by <scan.  Command lines might be of the format:
.skip 1
.indent 21
mumble mumble /SWITCH /SWITCH
.SKIP 1
.flag capital
In this case, the "mumble mumble" portion of the command could
be parsed by the user program, and <pscan would be used to
do the "/SWITCH" processing.
An example of a <pscan user is <credir.
.index CREDIR
.ski2
.test page 15
.break
.hl1 SWITCH-FORMATS:
.break;.subtTL Switch Formats
.index SWITCH FORMATS
.skip 2
.autopar
 The general formats of a switch specification are quite simple -- which format a particular switch will require depends on
how it is defined in the SWTCHS Macro (described later).
 
.TEST PAGE 3
.break
 The simplest switches are those which take no value -- it is their presence (or absence) which is important.  The presence of
the switch will cause SCAN to deposit a predefined value into a predefined memory byte or word.
It is also possible for these switches to be, in effect, three-way rather than two-way.  Either the switch is absent,
present, or present with "NO" prefixed to it.  Examples of these types of switches are:
 
.LM6
.TEST PAGE 4
.break
.ski 1
/FAST
.break
/HELP
.break
/MAP
.break
/NOMAP
.break
 
.ski 2
.LM1
.TEST PAGE 3
.break
 The second type of switch is one that takes a value (or values) which must be part of a pre-defined list of legal values
for that switch.  The "value" of the switch is then the numeric index, into the table of legal values, of the value
specified.  For example, if the legal values for "/MODE" were "ASCII, OCTAL, SIXBIT, DECIMAL," then:
 
.TEST PAGE 3
.break
.LM6
.ski 1
/MODE:OCTAL      	value = 1
.break
/MODE:DECIMAL    	value = 3
.break
/MODE            		is illegal
.break
.ski 1
.TEST PAGE 3
.break
.LM1
 A variation of this switch allows for defaults when:
.skip 1
.lm 3
.list 0,'o'
.le
The switch was not mentioned.
.indent -3;or
.le
The switch was mentioned, but without an explicit value.
.end list
.LM 1
.TEST PAGE 3
.break
.skip 1
.LM1
 The third type of switch is one that takes a more or less arbitrary value.  This value can be anything the user desires.  
SCAN is supplied with the name of a routine to "pick-up" the value, and a description of where and how to store the value.
If desired, a maximum value may be specified.  In addition, the comment above about defaults for Type 2 switches also holds
here.  The switch may be defined to take only one value, or to take many values.  Typical values are numbers and file
specifications.  Examples are:
 
.TEST PAGE 5
.break
.LM6
.ski 1
/WIDTH:75
.break
/ABCD:(12,34,56,78)
.break
/FILE:MYFIL.MAC[70001,1]
.break
.ski 1
.LM1
.TEST PAGE 5
.break
The three basic switch types can be summarized as:
.LM6
.skip 1
TYPE 1 - no value
.break
TYPE 2 - specific values only
.break
TYPE 3 - arbitrary values
.ski 4
.LM1
.TEST PAGE 4
.break
.hl1 FILE-SPECIFICATIONS
.INDEX FILE SPECIFICATION FORMAT
.break;.subttl File Specifications
.skip 1
 The format of a file specification for SCAN is quite general.  No ordering between the components is either expected or
necessary.  The basic parts of a file-spec are:
.skip 1
.TEST PAGE 3
.break
.list 1,'o'
.le
DEVICE:     1-3 SIXBIT characters followed by a colon.
.le
FILENAME:   1-6 SIXBIT characters.
.TEST PAGE 3
.break
.le
EXTENSION:  1-3 SIXBIT characters, preceeded by a period.
.TEST PAGE 8
.break
.le
PPN:        A Project Number
(1-377777 octal),   a Programmer Number
(1-377777 octal) and (optionally) an SFD specification, in one of the following arrangements:
.ski 1
.TEST PAGE 15
.lit
	[PROJECT,PROGRAMMER]
	[PROJECT,PROGRAMMER,sfd,sfd,...]
	[,PROGRAMMER]               uses logged-in PROJECT
	[,PROGRAMMER,sfd,sfd,...]         -dittoe-
	[PROJECT,]                  uses logged-in PROGRAMMER
	[PROJECT,,sfd,sfd,...]            -dittoe-
	[,]                         uses logged-in PPN
	[,,sfd,sfd,...]                  -dittoe-
	[-]                         uses default path
.end lit
.le
SWITCHES:  
Any of the switches described later as "Internal Scan Switches."
(See "FILE-SPEC SCANNING.")
.end list
.break;.subttl	Defaults
.test page 12
.break
.hl1 DEFAULT VALUES FOR SWITCHES
.INDEX DEFAULT VALUES
 When the user calls SCAN, he has the option 
of specifying a set of defaults for any of the above components.  SCAN will use
these defaults in the event that the user does not specify the corresponding component of the specification.
More of this topic is covered in detail in a later chapter --
"DEFAULT VALUE HANDLING."
.index defining switches
.index swtchs macro
.CHAPTER DEFINING SWITCHES - THE "SWTCHS" MACRO
.INDEX SWTCHS MACRO - USAGE
.INDEX DEFINING SWITCH PARAMETERS
.ski 4
.hl1 DEFINING SWITCHES - "SWTCHS" MACRO
.break;.subttl SWTCHS, DOSCAN
 The purpose of this chapter is to cover the topic of switch definition.
it is necessary for the user program to provide <scan with information
on the switches to be parsed.  This includes data such as the switch name,
the type of argument, if any, where to store the parsed values,
and the like.  The definition process has been made relatively
simple and painless by the use of macros supplied by
<scnmac.
.hl1 SWTCHS _& DOSCAN -- USAGE
.INDEX DOSCAN MACRO
.INDEX DEFINING SCANNER TABLES
 The properties of each switch to be 
scanned for are defined via a set of MACROs provided by SCAN.  There is always a 
one-to-one correspondence between a switch and its MACRO specification.  These switch MACROs are all included within a user
defined MACRO called "SWTCHS".  The definition of SWTCHS is of the following simple form:
.ski 3
.TEST PAGE 8
.break
.indent 10;DEFINE SWTCHS _<
.noautopar
.break
.indent 10;  macro-call . . . .
.break
.indent 10;  macro-call . . . .
.break
.indent 10;     #######.
.break
.indent 10;     #######.
.break
.indent 10;     #######.
.break
.indent 10;  macro-call . . . .
.break
.indent 10;_>;END OF SWTCHS MACRO
.break
.ski 2
.autopar
.TEST PAGE 4
.break
 Once the switches are defined in SWTCHS, the scanning tables are generated by calling the macro "DOSCAN".  The format of
this call is:
 
.ski 1
.indent 10;DOSCAN (NAME)
.INDEX DOSCAN MACRO
.break
.ski 2
where "NAME" is a legal MACRO-10 label from 1-5 characters.  The tables generated for use by <scan will have labels of the form "NAMEx,"
where "x" identifies the specific table.  The tables involved are:
.skip 2
.TEST PAGE 3
.break
.LM 3
.list 1,'o'
.le
nameN -
The table of switch names (in SIXBIT), one per word.
.le
nameD -
The table of default values.
.le
nameM -
The table of routine addresses for processing switch values.
.le
nameP -
The table of pointers used for storing values.
.le
nameL -
This symbol's value is the length of each of the above tables.
.end list
.LM 1
.break;.subttl SS, SN, SL _& SP
.LM1
.hl1 SWTCHS -- DEFINITION
.INDEX SWTCHS MACRO - DEFINITION
 There are four switch defining macros 
(USED WITHIN <SWTCHS)
which are described below:   
$S$S ($Switch-$Storage), $S$N ($Switch-$Name), $S$L ($Switch-$List), and
$S$P ($Switch-$Pointer).
fsyntax
A "typical" switch-table definition
might now look like:
 
.LM6
.TEST PAGE 7
.break
.ski 1
DEFINE SWTCHS _<
.noautopar
.break
   SS...
.break
   SN...
.break
   SL...
.break
   SP...
.break
_>
.break
DOSCAN (TEST)
.break
.lm 1
.ski2
.LM1
.autopar
.TEST PAGE 4
.break
The switch macros and their parameters are:
.skip 1
.LM 3
.list
.le
SS - 
.INDEX SS MACRO
.INDEX MACROS - SS
.INDEX SWITCH TYPES - SS
This is for switches described above as "TYPE 1".  No value is specified on the command line; instead, a pre-defined value is stored.  The SS format is:
.skip 1
.break
	SS NAME, STORAGE, VALUE, FLAGS
.skip 1
.break
 
.TEST PAGE 3
.break
When the switch is encountered, VALUE will be placed in the location described by STORAGE.  FLAGS are scan-controlling
flags which will be described later.  STORAGE may be an address or a byte pointer.  Use of the POINTR macro  for defining the STORAGE field
latter is described later.  An example of SS usage is:
.skip 1
.break
	SS MAP,MAPLOC,1,0
.skip 1
In this case, "1" is stored in MAPLOC if /MAP is seen on the command line.
.le
SN - 
.INDEX MACROS - SN
.INDEX SN MACRO
.INDEX SWITCH TYPES - SN
This is also for "TYPE 1" switches, in the cases  where "NO" may be prefixed to a switch's defined name.  The SN format is:
.skip 1
.break
	SN NAME, STORAGE, FLAGS
.break
.skip 1
 If the switch is encountered without the "NO" prefix, STORAGE takes the value "1."##If the prefix "NO" is included, the value of
STORAGE is then "0."
STORAGE and FLAGS are as defined for SS.
For example:
.skip 1
.indent 5;SN INTERCHANGE,INTLOC,0
.SKIP 1
If /INTERCHANGE were define in this manner, then whenever /INTERCHANGE appeared on
the command line, "1" would be stored in INTLOC (as would be the case
with SS).  However, if /NOINTERCHANGE were seen (which would not be
legal using SS unless a seperate SS definition were made), then
"0" would be put into INTLOC.
.le
SL - 
.INDEX SL MACRO
.INDEX MACROS - SL
.INDEX SWITCH TYPES - SL
This is used to define "TYPE 2" switches; those with one of a specific set of values.  Associated with this
macro are two others -- "KEYS" and "DM" -- which are called &o&u&t&s&i&d&e of
SWTCHS.  The SL format is one of:
 
.ski 1
.indent 10;SL NAME,STORAGE,TABLE,DEFAULT,FLAGS
.indent 10;SL NAME,PROCESSOR,TABLE,DEFAULT,FLAGS
.break
.ski 2
.TEST PAGE 7
.break
 STORAGE and FLAGS are as described for SS formats.  PROCESSOR is used to specify a non-standard (i.e.: non-SIXBIT) input routine.
This routine is then also responsible for storing the value as well.
TABLE and DEFAULT are names associated with the KEYS and DM macros, respectively.
.TEST PAGE 3
 The value placed in  STORAGE will be the index into the table of values generated by KEYS.  The format of the MACRO-10 labels generated
are described below with the KEYS macro.  An example of the SL format is:
.ski 1
.indent 10;SL PARITY,PARLOC,PARY,PAR,
.break
.ski 1
.TEST PAGE 3
.break
This will be explained once the KEYS and DM macros are described below.
.skip 1
.TEST PAGE 3
.break
.le
SP - 
.INDEX MACROS - SP
.INDEX SP MACRO
.INDEX SWITCH TYPES - SP
This format is used with "TYPE 3" switches; those which take an arbitrary value, possibly less than a predefined maximum.
The SP format is:
.ski 1
.indent 10;SP NAME,STORAGE,PROCESSOR,DEFAULT,FLAGS
.break
 STORAGE and FLAGS are as described above for SS.  PROCESSOR is the address of the routine (either SCAN or User-supplied)
to "pick-up" the value.  This routine must leave the value in P3 if it wants SCAN to store it.  The routine must return
+1 for SCAN to store the value, or +2 for SCAN to not store the value.  DEFAULT is as described for SL and may be null
if no defaults (or maximum value) are desired.  Examples, which will be explained in more detail later, are:
.ski 1
.indent 10;SP  PROTECTION,PROTEC,.OCTNW_#_#,,0
.indent 10;SP  PROTECTION,PROTEC,.OCTNW_#_#,PRO,0
.break
.ski 2
.end list
.LM 1
.TEST PAGE 18
.break
.LM1
 Each of these macros will uniquely identify and describe a switch in terms of the following characteristics:
.skip 1
.LM 3
.list 0,"o"
.le
Its name.
.le
Where to place its value, if any (STORAGE).
.TEST PAGE 3
.break
.le
How to read its value, if any (PROCESSOR).
.TEST PAGE 3
.break
.le
What its legal values, if any, are (TABLE).
.le
What its default and maximum values are, if any (DEFAULT).
.le
The syntax in which it may or may not be used (FLAGS).
.end list
.LM 1
.ski1
.break
.hl1 SCAN - CONTROLLING FLAGS:
.INDEX SCAN CONTROLLING FLAGS
.break;.subttl FS.??? Flags
.INDEX FS.??? FLAGS
 
 Each switch may have associated with it a combination of any of the following flags.  These flags control how the
switch may be used in a  command line.
 
.LM 3
.list 1,'o'
.le
>FS.VRQ -
.INDEX SCAN FLAGS - FS.VRQ
A value is required.
.le
>FS.NFS -
.INDEX SCAN FLAGS - FS.NFS
The switch is never part of a file-specification.
This switch should be meant as a global switch.
.le
>FS.LRG -
.INDEX SCAN FLAGS - FS.LRG
The maximum and default values are 0 or greater than 2**17.
If set, and the maximum value (in DM macro) is set, then 36-bit
values for this switch are possible.  Otherwise, only 18-bit
values are legal.
.le
>FS.NCM -
.INDEX SCAN FLAGS - FS.NCM
This switch is not a command switch (for VSCAN).
.le
>FS.NUE -
.INDEX SCAN FLAGS - FS.NUE
No user exit on this switch.  This means that /EXIT and _^Z
do not cause an exit via MONRET, as they normally would.
.le
>FS.OBV -
.INDEX SCAN FLAGS - FS.OBV
"OR bit values."   This causes the value of the switch to
be OR-ed with whatever existing value may already have been
stored.  Normally, the old value in the STORAGE location is overwritten.
If this flag is set, then
SCAN will LDB the existing value, IOR in the value of the
switch as  just parsed, and then DPB the value back to
storage again.
.le
>FS.NOS -
.index SCAN FLAGS - FS.NOS
For the SN macro calls only:  This switch may take "NO" as a prefix.
.end list
.LM 1
.CHAPTER THE "DM" _& "KEYS" MACROS
.INDEX DM MACRO
.INDEX KEYS MACRO
.INDEX MACROS - DM
.INDEX MACROS - KEYS
.LM1
.ski4
.hl1 THE "DM" AND "KEYS" MACROS
 These two scanning macros are those related to:  1) default (and maximum) values, and 2) values for "TYPE 2"
.INDEX DEFINING DEFAULT VALUES
.INDEX DEFINING VALUES FOR SL SWITCHES
(SL) switches.  These were mentioned above in the discussions of the SL and SP macros, and will now be described
in detail.
.BREAK
.hl1 DM -- MAXIMUM _& DEFAULT VALUES
.break;.subttl "DM"
 In order to supply SCAN with a set of default and maximum values, the programmer supplies a 1-3 character
name in the SL or SP macro, in the field DEFAULT.  After SWTCHS has been defined, DM is called for each switch
referencing it.  A DM call has the form:
.ski 1
.indent 10;DM (NAME,MAX,ABSENT,PRESENT)
.ski 1
.indent 10;where:
.ski 1
.indent 10;NAME#####is the 1-3 character name in the SL or SP
.INDEX MX.????
.INDEX AD.???
PD.????

.indent 10;#########call.
.indent 10;MAX######is the maximum value.
.indent 10;ABSENT###is the default value if the switch is not 
.indent 10;#########encountered.
.indent 10;PRESENT##is the default value if the switch is 
.indent 10;#########present, but without a value.
.break;.subtitle "DM"
 
.LM1
.TEST PAGE 3
.break
 Each of these values is given a symbolic name, if the name already is defined, then the existing definition takes
precedence over the DM argument.  The three symbol names are of the respective forms:
.ski 1
.lm6
MX.NAME     AD.NAME     PD.NAME
.ski 1
.TEST PAGE 3
.break
.LM1
An example will clarify this somewhat.  Given the following:
 
.LM6
.ski 1
DEFINE SWTCHS _<
.break
SP PROTECTION,PROTEC,.OCTNW_#_#,PRO,0
.break
_>
.break
DM (PRO,777,057,155)
.break
.skip 2
.LM1
.TEST PAGE 3
.break
 This defines a switch "/PROTEC" whose maximum value is "777".  If the switch is not in the command
line, THE PROGRAM (not SCAN) may use the symbol AD.PRO for the value, which may be "057."  If only "/PROTEC" is in the command
string, then the value stored BY SCAN will be that of PD.PRO, in this case "155".
.TEST PAGE 10
.break
.hl1 KEYS - KEYWORD DEFINITION
.break;.subttl "KEYS"
.INDEX KEYS MACRO
.INDEX MACROS - KEYS
.INDEX DEFINING KEYWORDS FOR SL SWITCHES
 "TYPE 2" (SL) switches always take 
a value from a predefined list of keywords.  These keywords must be made from the
SIXBIT characters, and are defined in the KEYS macro.  The SL macro's TABLE field is then used as an argument
to KEYS.  KEYS is called after SWTCHS is defined (just like DM is).  The call is of the form:
.ski 1
.TEST PAGE 3
.INDENT 10;KEYS (NAME,WORD1,WORD2,...WORDn)
.skip 1
.INDENT 10;where:
.ski 1
.INDENT 10;NAME is the 1-4 character name from the SL call.
.break
.INDENT 10;WORD1 is the first possible value.
.break
.INDENT 10;WORD2 is the second possible value.
.break
.INDENT 10;WORDn is the last possible value.
.break
.ski 2
.TEST PAGE 3
 The table of values is given the name NAME.T and is of length NAME.L.  Each possible value's position
in the table is the value of the symbol
NAMExx, where "xx" are  the first two characters of the value.  This implies that 
if these SCAN constructed symbols are to be used by the program (not a necessity), then
all keywords must be unique in their
first two letters.
 
.TEST PAGE 10
 Once again, an example is in order.  Consider the following:
.TEST PAGE 5
.ski 1
.INDENT 10;DEFINE SWTCHS _<
.break
.INDENT 10;SL  PARITY,PARLOC,PARY,PAR
.break
.INDENT 10;_>
.break
.INDENT 10;KEYS  (PARY,EVEN,ODD,NONE)
.break
.INDENT 10;DM   (PAR,PARY.L,PARYNO,PARYOD)
.break
.skip 2
 This generates a switch "<parity" which takes as a "value" of
of the following keywords:
.skip 1
.indent 10;EVEN
.INDENT 10;ODD
.INDENT 10;NONE
.SKIP 1
The default is "NONE" if only "/PARITY" is seen in the
command without an explicit value.   If the "/<parity" switch is
missing from the command line altogether,
then the default value (not supplied by SCAN) is "ODD".
The location "<parloc" will receive the "value" of the
switch, which is determined by the order in which the
keywords are listed in the KEYS macro:
.skip 1
.indent 10;EVEN=0
.INDENT 10;ODD =1
.INDENT 10;NONE=2
.SKIP 1
 The maximum value for such a switch is the VALUE (not the contents)
of the symbol "PARY.L" (ie, the 1-4 character designater used in  KEYS,
with ".L" catenated to the right).
 The elemets of the DM call specifying the defaults may be the symbolic
names constructed by the KEYS call, or the actual values (as literals
or non-SCAN defined symbols) values.  The later is normally undesireable,
as it makes changing a switch's characteristics difficult, but is 
used when the possible values (keywords) cannot be unique in their first
two letters.  If the non-unique values are not to also be default or maximum
values, then this poses no real problem (since the assembler will simply
use the latest definition it encounters).
.hl1 CONSTRUCTED SYMBOLS - SUMMARY
 The previous sections has covered a number of symbols used by SCAN
and its support code that are created by the SCAN macros themselves.
To summarize them:
.skip 1
.list 0,"o"
.le
MX.??? - ??? is first arg to DM; this is created by DM as the maximum value for the switch
.index MX.???
.le
AD.??? - as above, but this is the absent default value for the support program to
.index AD.???
.INDEX DEFAULTS - ABSENT
use if it sees fit.
.le
PD.??? - as above, but this is the present default value for the switch, used
.INDEX PD.???
.INDEX DEFAULTS - PRESENT
by SCAN.
.le
????.L - ???? is the first agr to KEYS; this is created by KEYS, and has as its value the length
.INDEX ????.L
.INDEX KEYWORD TABLE - LENGTH
of the table of keywords created by KEYS for this switch.
.le
????.T - as above, but this is the address of the table of keywords created
.INDEX ????.T
.INDEX KEYWORD TABLE - ADDRESS
by KEYS.
.le
????XX - as above,
.INDEX ????XX
.INDEX KEYWORD TABLE - ENTRIES
but this is the index into ????.T for the keyword whose first 2 characters
are XX.
.le
.INDEX ?????N
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
.INDEX SWITCH TABLES - NAMES
?????N - ????? is the arg to DOSCAN (see previous chapter); this is the
table of switch names.
.le
?????D - as above, this is the table of default values
.INDEX ?????D
.INDEX SWITCH TABLES - DEFAULTS
.le
?????M - as above,
.INDEX ?????M
.INDEX SWITCH TABLES - PROCESSORS
this is the table of processor routines for the switch
.le
?????P - as above, this is the table of information for storing values.
.INDEX ?????P
.INDEX SWITCH TABLES - STORAGE
.le
?????L - as above, this is the length of the other tables created by DOSCAN.
.INDEX ?????L
.INDEX SWITCH TABLES - LENGTH
.end list
.CHAPTER DEFINING THE "STORAGE" FIELD
.break;.subtitle POINTR MACRO
.ski4
.hl1 DEFINING THE "STORAGE" FIELD
.index defining the storage field
 All of the Switch macros have the field denoted "STORAGE."##This field can have a number of formats,
sometimes depending on the switch macro itself.  Each of the formats will be described
here.
.hl1 THE POINTR MACRO
 One of the principle uses of STORAGE 
is as a byte pointer.  Because of this, it is useful to first mention the use of the POINTR
macro, since it is quite often the method used to define the STORAGE field.
 This macro is used to define a byte pointer, given:
1) the definition of the byte in terms of a mask, and 2) the storage location containing the byte.
An example might prove useful here.
Suppose a word "Y" contains a byte "X," consisting of bits 11 through 19.  The POINTR usage would then be:
 
.TEST PAGE 3
.LM6
.ski 1
X=177600000; mask for bits 11-19
.break
POINTR (Y,X)	
.break
.ski 2
.LM1
.TEST PAGE 3
If "X" were changed to be some other byte, either  in "Y" or in some other location,
the only change needed would be to its
definition; references to it via the POINTR macro would not need changing
.index POINTR MACRO
.TEST PAGE 15
.BREAK
.skip 1
.hl1 STORAGE FIELD
 There are five formats for STORAGE:
 
.list 0
.le
Word Address.  (SN,SS,SP,SL)
.index SN MACRO
.INDEX MACROS - SN
.INDEX SS MACRO
.INDEX MACROS - SS
.INDEX SP MACRO
.INDEX MACROS - SP
.INDEX SL MACRO
.INDEX MACROS - SL
.INDEX SCAN SWITCHES - SN
.INDEX SCAN SWITCHES - SS
.INDEX SCAN SWITCHES - SP
.INDEX SCAN SWITCHES - SL
.le
Byte Address.  (SN,SS,SP,SL)
.le
Pointer to multiple-value storage.  (SS,SP,SL)
.le
Pointer to a file-specification storage area.  (SP)
.le
Address of a routine to process keyword.  (SS,SP,SL)
.end list
.LM 1
.LM1
.TEST PAGE 3
 For all formats except _#1, STORAGE is in the format of a PDP-10 byte pointer,
although it may not always be used as such.  The exact format definitions for the five types, in order are:
 
.TEST PAGE 3
.LM 2
.list 1
.le
(LH)=0
.break
(RH)=word address; value is MOVEMed into the storage address.
.le
Standard byte pointer format; value is DPBed into the storage field.
.le
The byte size field contains the number of words in the storage area, in the form (65-_#words).  (RH)
points to the first word.
.le
This is implicit:  ".FILIN" will have been given as the PROCESSOR. (RH) is the address of
.INDEX .FILIN
.INDEX STORAGE FIELD - FILE SPECIFICATION
the SCAN storage area (see later discussion of SCAN blocks).  The length of this area (see later discussion of SCAN blocks) is the value of MX.NAME (from the DM call), which would otherwise
.index SCAN BLOCKS
have no meaning in this context.
.le
Bits 0 through 11 in the "byte-pointer" being all 1s means that (RH) is the dispatch address of a processor which
will "pick-up" the keyword.e a dummy symbol to be the required value,
The easiest method of specifying such a value (getting both the size and
position fields to be 1s) is to deine a dummy symbol to be the required value,
and to then use that symbol in the STORAGE field.
.end list
.LM1
.ch DEFAULT VALUE HANDLING
.hl1 INTRODUCTION
 In Chapter five ("THE 'DM' AND 'KEYS' MACROS"), the concept of specifying
default values for the various switches was introduced.  This
chapter will cover the topic in more detail.  Both SCAN-supplied
and user-supplied default values will be covered.  This is an especially
important area, since it is something many believe should
be provided by SCAN directly, that the user program should
not be forced to become involved with.  Because of this, it is
also important to notice when the standard DEC SCAN is being
referenced, and when the modified SCAN is being referenced.
.hl1 FILE SPEC DEFAULTS
 The "DM" macro gives the user the ability to specify 
defaults, but the user program must also do the enforcement of
some of
those defaults. This is especially true of default values used
when the switch is absent on the command line: SCAN will
not go through the tables DOSCAN produces to see what
switches were not specified, to be able to apply the appropriate
default values.  This entire area is one of the gaping
holes in SCAN.
.test page 10
.break
.hl1 ABSENT DEFAULTS vs PRESENT DEFAULTS
 When the DM macro was introduced, the point was made that
two default values are allowable.  One is the default value
to be used whenever the switch is absent from the command
line (absent default), and the other is the default value
to be used when the switch is given, but without an
explicit value (present default).  The arguments given
to DM are in the following format:
.skip 1
.indent 10
DM	(ABBREV,MAX,ABSENT,PRESENT)
.SKIP 1
.INDENT 10;where:
.skip 1
.indent 10;ABBREV is the 1-3 char name used
.indent 10;########in the SL or SP macro
.indent 10;MAX     is the maximum value
.indent 10;PRESENT is the present default
.indent 10;ABSENT  is the absent default
.skip 1
.indent 10;which generate the following symbols:
.skip 1
.indent 10;MX.ABBREV (maximum value)
.indent 10;PD.ABBREV (present default)
.indent 10;AD.ABBREV (absent default)
.skip 2
 The generated symbols are always global, and will never
re-define prior values.  In other words, one can manually give
values to some of the symbols to which DM normally assigns values,
then call DM, without having the manually assigned
values destroyed.
 This discussion leads one to expect that SCAN will perform
the following functions when it is processing switches,
or when it is applying default values (as in .APLST):
.INDEX .APLST
.list 1,'o'
.LE
Range check values to be sure they
are within 0_<=MX.ABBREV
.LE
Give PD.ABBREV as the value when only /SWITCH is seen
on the command line
.le
Give AD.ABBREV as the value when /SWITCH is not seen
on the command line at all
.end list
 However, only _#1 and _2 are supported by SCAN at the present
time.  The generation of the AD.ABBREV symbols by DM is solely
for use by the program which is using SCAN.
Such support is planned for the next release of the
modified DEC SCAN.  The text below will outline the steps
necessary to support this in a user program.  The envisioned
support within the modified SCAN will be in one of two forms:
.list 1,'o'
.le
Additional code to .APLST, so that all switches are defaulted whenever
file specifications are.  It is not clear that this is the
way to go, since it is sometimes desirable to seperate the handling
of file-spec and non-file-spec switches.  This is the reason,
for instence, for the existence of the FS.NFS (Not a File Switch)
flag.
.le
The inclusion of an additional routine,
which will default the user switches.  This is
the preferable method, and (more than likely) the one which
will be used.
.end list
.hl1 IMPLEMENTING SUPPORT OF ABSENT DEFAULTS
 This support consists of two distinct phases:  assembly
time generation of necessary table(s), and execution time
code to scan the SWTCHS tables (as well as the added one(s)).
There is no real problem or difficulty in either of these.
.hl2 GENERATING TABLES AT COMPILE TIME
 This task will be performed immediately after the usual call
to DOSCAN, and will generate a table using the SWTCHS macro.
One must be careful to check to see if an absent default
has indeed been given for each switch.  Since the
AD.ABBREV symbols are not used for any other purpose, the
problem of determining whether or not a switch is eligible for
defaulting is conveniently avoided.  One possible macro might be
the following, which generates the table "xxxxxA":
.skip 1
.test page 17
.break
.indent 10;DEFINE DODFLT(NAME),_<
.SKIP 1
.INDENT 10;DEFINE X(_$NAME,_$PROC,_$POINT,_$DEFLT,_$MAX,_$FLAGS),_<
.INDENT 10;IFNDEF AD.'_$DEFLT,_<
.INDENT 10;Z		;_$NAME - NO ABSENT DEFAULT
.INDENT 10;_>
.SKIP 1
.INDENT 10;IFDEF AD.'_$DEFLT,_<
.INDENT 10;XWD	400000,AD.'_$DEFLT	;_$NAME
.INDENT 10;_>
.INDENT 10;_>  ;END OF DUMMY MACRO "X" FOR SWTCHS
.SKIP 1
.INDENT 10;NAME'A::
.INDENT 10;SWTCHS
.INDENT 10;_>  ;END OF DODFLT MACRO
.SKIP 2
 The table "xxxxxA" is organized is such a manner that
the sign bit indicates whether or not an absent default is
applicable for this position's switch.  When the
sign bit is on, the right half of the same word is
the absent default.  If it is off, the rest of word
is ignored.
.hl2 EXECUTION TIME SUPPORT CODE
 The other task to be performed is the writing of code
to be called at about the same time
_.APLST is called, but AFTER .OSDFS is called to apply
_.OSCAN's default values.  The procedure to follow
is simple.  The following code gives a possible method.
.TEST PAGE 10
.BREAK
.skip 1
.lit
	.APLDF::HRLZI	T1,-xxxxxL
	LOOP:	SKIPL	T2,xxxxxA(T1)
		JRST	ENDLUP
		MOVE	T3,xxxxxP(T1)

	;determine how to store value
	;see the code around SWDPBE in SCAN

	ENDLUP:	AOBJN	T1,LOOP

	;here with all absent defaults applied
.end lit
.skip 2
 As this example indicates, some thought needs to be given at the point
where the value in T2 is to be stored via the contents of T3.
T3 can take various forms, although it is usually a standard
byte pointer.  The principle exception in this context is
when the switch allows multiple arguments, and the
STORAGE field in SWTCHS is used to specify the  length and location
of the area in which to store the values.  The other
exception is the case where a full word is to be stored for the
value, in which case the left half of the "pointer" is zero, and the
right half is the location to store the value. 
 As the example also
indicated, the method for properly handling this is in SCAN,
in the routine SWDPBE, which is where all values for switches
are stored.  In this code, P2 is pointing to a 4 word table
containing the addresses of the tables produced by DOSCAN.
The offsets in this table are given the names:
.skip 1
.TEST PAGE 8
.BREAK
.indent 10;SWN==0   (xxxxxN)
.indent 10;SWP==1   (xxxxxP)
.indent 10;SWM==2   (xxxxxM)
.indent 10;SWD==3   (xxxxxD)
.skip 1
P1 is used to index into the "xxxxx?" tables to access the
entries for the current command (ie:  xxxxxN(P1) is the <sixbit
name of the current command, etc.).
Knowing this, it is not difficult to follow the 
logic of the code.
.hl1 SUMMARY
 The purpose of this chapter is to provide information on
handling default values.  The defaults catagorized as
"present defaults," which are used whenever the switch is
specified but its value is not, are already handled completely
by SCAN.  The other catagory - "absent defaults" - are
not handled in any way be the current version of SCAN.
The method in which this will be implemented in a future
version of the modified DEC SCAN was presented.  In addition,
the general method for implementing this in a user
program was given.
.CHAPTER FILE-SPECIFICATION SCANNING
.LM1
.ski3
.hl1 FILE-SPEC SCANNING
.INDEX FILE SPECIFICATION INPUTTING
.INDEX INPUTTING FILE SPECIFICATIONS
 An earlier section (The Command Scanners) gave a detailed description of what a file-specification is.  What is of concern
here is the use of .FILIN, the SCAN routine for inputting a file-spec.
.hl1 SCAN BLOCKS
.hl2 DEFINITION
.break;.subttl Scan Blocks
 Crucial to this topic is a discussion 
of what is called a "Scan-Block," which is SCAN's internal (mostly) 
representation of the information relevant to the file-spec which was scanned.  Appendix D ("SCNMAC")
contains the exact definitions of the words and bits
in a Scan-Block.  Generally speaking, the information includes:
 
.TEST PAGE 16
.LM 3
.list 1,'o'
.le
Device name.
.le
Filename and its mask.
.le
Extension and its mask.
.le
PPN and its mask, along with any PATH information.
.le
Selection criteria, based on switches encountered (dates, times, etc.).
.le
Indications of the various switches' presence or absence.
.le
Syntax representations.
.end list
.LM 1
.LM1
.TEST PAGE 3
.hl2 SCAN'S BUILT IN SWITCHES
.break;.subttl Built-in Switches; Guide Words
 The switches referred to were mentioned 
earlier as "Internal SCAN Switches."##These are mostly used to specify file
selection criteria, especially for use by >WILD (see Appendix B).  The exact definitions are included in Appendix E as one 
of the examples of Switch definitions.  Summarized, they are:
.skip 3
.test page 25
.LM17
.INDENT -16
/ABEFORE
.INDENT -16
/ASINCE#######-#specify access-date-time criteria
.INDENT -16
/BEFORE 
.INDENT -16
/SINCE########-#specify creation-date-time criteria
.INDENT -16
/ERNONE
.INDENT -16
/OKNONE#######-#specify if no file-match is an error
.INDENT -16
/ERPROTECTION
.INDENT -16
/OKPROTECTION#-#specify if access-protection failure is an error
.INDENT -16
/ERSUPERSEDE
.INDENT -16
/OKSUPERSEDE##-#specify if it is an error to overwrite an existing file
.INDENT -16
/ESTIMATE#####-#specify an estimated file size
.INDENT -16
/EXIT#########-#go to monitor
.INDENT -16
/HELP#########-#type a help message
/NOOPTION#####-
.LM17
.INDENT -16
/OPTION#######-#control the use of options file (see "OSCAN")
.INDENT -16
/PHYSICAL#####-
set the "physical only" bit on all OPENs.
.INDENT -16
/PROTECTION###-#specify the protection of a file
.INDENT -16
/VERSION######-#specify#the#version#number#of#a#file
.INDENT -16
/RUN##########-
.INDENT -16
/RUNCORE######-
.INDENT -16
/RUNOFFSET####-#control the running of a new program when done with this one (see "Routine Call Definitions.")
.LM1
.TEST PAGE 4
.hl2 SYNTAX REPRESENTATIONS
.index Guide Words
 "Syntax Representations" refer to bits, 
used primarily by WILD, indicating what special constructs were seen.  These
are made up of usages of what SCAN terms "Guide Words," which are in a sense pseudo-characters.
The legal Guide Words, and their pseudo-character values, are:
 
.LM12
.ski 1
.LIT
'AND'  4000     'INPUT'  4005
'OR'   4001     'OUTPUT' 4006
'NOT'  4002     'SOURCE' 4007
'FROM' 4004     'LIST'   4010
'TO'   4003     'OBJECT' 4011
.END LIT
.skip 1
 
.LM1
.TEST PAGE 4
These are used to express inter-filename relationships in a command string, along with the concatenation operator -- the plus
sign.
Refer to "INPUT ROUTINES - CHARACTER" in Chapter 2, and to Appendix D - 
"SCNMAC."
.HL2 SCAN BLOCKS:  SUMMARY
 So much for Scan-Blocks.  It is important to 
realize that they exist, especially if any of the switches listed are
of use to the program, or if the user is interfacing with >WILD (which requires Scan-Blocks for input).  The .STOPB
routine (see "Routine Definitions") is used to convert these blocks to OPEN and LOOKUP/ENTER blocks.
 
.break;.subttl Scan Block Locations
.TEST PAGE 12
.skip 1
.hl1 F.EZER _& P.EZER
 The Scan-Block used by SCAN is located at the global symbol "F.ZER", and extends to "F.EZER".  Associated with this is a 
"default region," into which the user places his default values, if any, before calling SCAN.  
The definitions of the offsets into those blocks are in <scnmac,
a listing of which is included in the appendices.  These symbols
have names of the format ".FX???".
This area extends from 
"P.ZER" to ".EZER", and should be zeroed if no defaults exist.  To have these defaults applied (after SCAN has
returned), one issues the call:
.SKIP 1
.lm 6
PUSHJ P,.APLST_#_#
.ski 1
.break
.lm 1
to apply what SCAN calls "sticky defaults."
This is covered future in a following Chapter,
"DEFAULT AND MAXIMUM VALUE HANDLING."
 Once the Scan block at F.ZER has had 
the user's defaults applied, then it remains to:  1) apply SCAN's defaults, and 2)
to move it to the user's area.  This is done in the following manner:
 
.test page 10
.break
.LM6
.ski 1
MOVEI T1, address  ;user's Scan-Block address
.break
MOVEI T2, length   ;length of same
.break
PUSHJ P,.GTSPC_#_#
.break
.ski 2
.LM1
.TEST PAGE 2
After this, the area of F.ZER can then be reused for more file-specs.
.hl1 _.STOPB
.index .STOPB
 Once the scan blocks  were created by SCAN, and possibly
processed by WILD (to resolve wild card expressions), the
problem remains of doing something with them.  The TOPS-10
monitor will certainly not accept them to specify file
operations.  What needs to be done is to covert from
the SCAN block format needed during scanning, to the
standard OPEN and LOOKUP/ENTER block format needed
during processing.  The routine whhich performs this task
is ".STOPB" (Scan To OPen lookup Block).
The call on .STOPB is of the format:
.skip 1
.indent 10;T1/#  SCAN-block-len,,SCAN-block-address
.indent 10;T2/###############0,,OPEN-block-address
.indent 10;T3/#LOOKUP-block-len,,LOOKUP-block-address
.indent 10;T4/###############0,,PATH-block-address (9 words)
.skip 1
.INDENT 10;PUSHJ##P,.STOPB_#_#
.INDENT 10;########-error- (wildcards not yet resolved)
.indent 10;########-ok- SCAN block is translated
.hl1 USING .FILIN
.break;.subtTL Sequence of Operations
 Now that all else has been taken care 
of, the actual scanning of file-specifications is simple to explain.  The
routine responsible for this is .FILIN, which is called in the following manner:
.skip 1
.lm 6
PUSHJ P,.FILIN_#_#
.skip 1
.lm 1
.TEST PAGE 2
.break
and returns with T1 containing:
 
.LM6
.ski 1
#0 if null expression
.break
-1 if file spec typed
.break
#1 if only switches seen
.break
.ski 2
 
.TEST PAGE 25
.LM1
.hl1 SUMMARY OF FILE SPEC SCANNING
 Summarizing the file-spec scanning process, 
we have seen that the following sequence is the general method used:
 
.LM 3
.list 1,'o'
.le
Setup defaults in P.ZER area
.le
Call .FILIN
.le
Call .APLST
.le
Call .GTSPC
.le
Call >WILD
.le
Call .STOPB
.le
Process LOOKUP/ENTER and OPEN blocks
.end list
.LM 1
.cHAPTER  _.ISCAN - SCANNER INITIALIZAITON
.LM1
.ski3
.hl1 ISCAN - Scanner Initialization
.index iscan
.INDEX .ISCAN
 Before calling one of the command scanners (or any input routine), it is necessary to give SCAN a set of
parameters and other information describing how the user intends to go about 
doing things.  In "ROUTINE CALL DEFINITIONS" a skeleton format of an ISCAN call was given, which is sufficient for a 
job interested in doing only simple TTCALL I/O, without any frills.  Here will be described in detail all of the
various options available via ISCAN.
.hl1 INITIALIZATION CONCERNS
 A number of procedures are followed by <scan during its
internal initialization, via <iscan.  These tend to revolve
around the one-time setting up of storage, for later use.
The specific functions, which are covered in detail in the following
paragraphs, include: Rescanning the command line which
initiated the program being run, determining how the program
was entered (CCL vs normal), what I/O routines to use,
what indirect files (if any) to use, etc.
Usually, many of these are not of great concern, and are
either omitted or defaulted to.
.hl1 RESCANNING THE COMMAND LINE
 While ISCAN is not a scanner, it will 
sometimes process part of the command line.  This occurs for programs which
accept input on the same line as the monitor line which activated them.  In these cases, ISCAN is given a list of the
valid monitor level commands to look for.  It then RESCANS the command line, and positions the input routines to the end 
of that command.  On return, T1 indicates whether a command was actually seen or not (see call description below).
If no table of commands is supplied, ISCAN will not do a RESCAN.
 One of the more common usages of this feature is in the writing
of a program which is to be invoked by a spsecific monitor command.  When commands are added to the monitor, in the module COMCON,
their dispatch address in COMTAB can be to a routine which
runs a program of the same name,, but starts it at the CCL
entry point (see the following paragraphs).  This makes it
possible for a program MUMBLE to be invoked by commands of
the format:
.skip 1
.indent 10;_.MUMBLE /switch:value /switch:value ...
.skip 1
In this case, .ISCAN would be told to perform the rescan of
the command line, in order to pick up the switches.  This is
the process used by programs such as DIRECT.
.test page 11
.break
.hl1 CCL MODE
 When a program is in what is usually termed "CCL mode," it was started with an offset other than 0
added to its start address.  In these cases, input usually comes to SCAN from a "CCL file."##In this case, ISCAN
must be told:  1) the 3-character CCL name, and 2) the value of the starting offset.  If not in CCL mode,
then ISCAN is given a zero word.
This feature is most useful for programs (such as DIRECT) which
can be monitor commands.
.test page 15
.BREAK
.hl1 I/O ROUTINES
 As was stated in the Introduction, SCAN defaults to TTCALL input and output.  If the user wishes, the address(es)
of special routine(s) for input or output may be given to SCAN.  Input routines must leave their character in P4;
output routines take theirs from T1.  Neither may destroy any other 
accumulators.
 If the program knows ahead of time that indirect file input will be used, and the name of the file, then a Scan-Block
form of the specification is passed to ISCAN.  The .FXDEV word must be non-zero for ISCAN to honor it.
.TEST PAGE 11
.hl1 PROGRAM TERMINATION
 Sometimes, it is useful for a program to always be given control whenever SCAN would otherwise return to the
monitor.  In these cases, a "MONRET" ("MONitor RETurn")
address is given to ISCAN.  In the absence of this, SCAN will simply issue an EXIT UUO.
.TEST PAGE 22
.break
.hl1 COMMAND PROMPTING
 Along the same lines, some programs have their own prompting schemes, and must supply ISCAN with the
appropriate address, which will later be PUSHJed to.  When it is called, T1 will be set up as
follows:
.skip 1
.LM12
.INDENT -6
(RH) the normal prompt character:
.break
"*" for first lines
.break
"_#" for continuation lines
.INDENT -6
(LH) 0 for first lines;
.break
-1 for continuation lines
.ski 1
.LM1
.TEST PAGE 2
A "continuation line" is one following a line which ended with a dash, which is SCAN's continuation
character.
.hl1 FLAGS
 This word specifies any special handling required.  The possible
flags are described below, and are also listed in the appendices
for SCNMAC and _$SCNDC.
.skip 1
.indent 5;>FS.ICL -
If set, whis will cause SCAN to "Ignore Command Line"
handling.  In other words, if the command line is not in a format
SCAN understands (such as LOGIN), but SCAN is used to
handle parts of it, the setting of this bit causes SCAN
to ignore the fact that it is actually a command line.
The RESCAN will still be done, however.
.skip 1
.TEST PAGE 2
.hl1 CALLING .ISCAN
.break;.subttl Argument Block Definition
 This brings us now to an exact description, 
which should make sense in the light of the preceeding paragraphs.
The calling format for .ISCAN is:
.TEST PAGE 25
.BREAK
.TEST PAGE 5
.LM6
.ski 1
MOVE# T1, [length,,argblock-address].
.break
PUSHJ P, .ISCAN_#_#
.break
##-return-
.break
 
.skip 1
.lm6
T1 = index into table of monitor
.break
commands, or -1 if none found
.break
.ski 2
 
.TEST PAGE 15
.break
.LM1
The argument block at "argblock-address" has the following format:
.ski 2
.test page 12
.break
.LM15
.INDENT -12
BLOCK:
.INDENT -12
BLOCK + 0 = 
0 or IOWD length, monitor-commands
.break
.INDENT -6
+ 1 =
(RH) 0 or address of starting offset
.break
(LH) 0 or SIXBIT CCL name
.break
.INDENT -6
+ 2 =
(RH) 0 or address of output routine
.break
(LH) 0 or address of input routine
.break
.INDENT -6
+ 3 =
0 or XWD length, indirect-Scan-Block
.break
.INDENT -6
+ 4 =
(RH) 0 or address of MONRET routine
.break
(LH) 0 or address of PROMPT routine
.break
.INDENT -6
+ 5 =
#####FLAGS
.break
.LM1
LENGTH==.-BLOCK
.break
.CHAPTER .TSCAN - THE TRADITIONAL SCANNER
.LM1
.ski3
.hl1 .>TSCAN - The Traditional Scanner
.index traditional scanner
  The most common command formats are those  with: 1) one output file-spec; 2) either one or more input-specs, or else no input spec at
all; and 3) command switches somewhere on the line.  This is the type of command line which TSCAN processes.  As well as needing
to know where DOSCAN's tables are, a few other issues come into play.
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
.hl1 /HELP
.break;.subttl Scan Block Defined
 One of the built-in "Internal Switches" listed 
above (see "File-Spec Scanning") was /HELP.  It now becomes
necessary to tell SCAN how to find the "HELP file" to be typed.  Four types of help are possible.
 
.LM 3
.list 1,'o'
.le
None
.le
Type a preset string
.le
Call a prenamed routine
.le
Call >HELPER
.end list
.LM 1
.LM1
.TEST PAGE 2
It is necessary for the caller to tell TSCAN which of the above to use.
.hl1 POST PROCESSING OF SWITCHES
 As a command line is processed, it is 
often desirable for the user to be given a chance to clear out various
storage areas, before a new command line is processed.  This is accomplished by passing to TSCAN
the address of a routine to PUSHJ to at the end of each line.
 
.TEST PAGE 2
 Along the same lines, there is often data to be cleared or reset as each file-spec is processed.  SCAN will zero
its F.ZER area, but the user may have other locations to worry about.  It may also want to change the P.ZER default
area.  To do so, the user provides TSCAN with an address to PUSHJ to.
.hl1 SCAN BLOCK ALLOCATION
 In the chapter on "FILE-SPEC SCANNING," it was indicated that SCAN assembles its data within its own core
(F.ZER) since the command line may very well contain many file-specs.  This means that some method must
exist for moving the Scan-Blocks to a "safer" area.
Since the input and output streams may require different handling, the user provides TSCAN with the addresses of two
routines which will allocate space for a Scan-Block.  These routines return the following information to SCAN:
.ski 1
.LM6
T1 = address of Scan-Block area
.break
T2 = length of Scan-Block area
.break
.ski 1
 
.LM1
.TEST PAGE 2
 The P.ZER area, as was mentioned earlier, contains the default file-spec values.  Often, information in one file-spec
on a command line is the default for a later file-spec on that line.  Because of this, SCAN will "memorize" this information
by copying the F.ZER information into the P.ZER area.  If the user would like control after this is done, an address to be 
PUSHJed to is passed to TSCAN.  Also, whenever SCAN applies the P.ZER defaults, the user may want to be called.  This is
also done by giving TSCAN the address to be PUSHJed to.  Finally, as the SCAN of a line is commenced, the P.ZER area is
cleared.  The user will then be called, if it had previously given TSCAN such an address.
.hl1 STICKY DEFAULTS
 A "sticky" default is what SCAN terms general globals defaults
for file specifications.  These are applied by SCAN when .APLST
is called.  When .TSCAN is called, the user has the option of
specifying a special routine to call whenever SCAN is going
to apply sticky defaults.  The left half of word number 6
contains the addresses of the routine to memorize sticky defaults for
all files, and the address of the routine to apply these
defaults to all succeeding file specifications:
.skip 1
.indent 10;XWD##MEMORIZE-ADDRESS, APPLY-DEFAULTS-ADDRESS
.SKIP 1
The other routine which may be specified it the routine to clear
any sticky defaults at the end of a file-spec scan.  This is
given in the left half of word number 7:
.skip 1
.indent 10;XWD##CLEAR-DEFAULT-ADDRESS, flags
If the user program has not sticky switches of its own,
then these fields should be left zero.  Otherwise, whenever
SCAN does its own sticky default handling, it will also can
on the user's routine to process the user's sticky defaults
at the same time.
.hl1 SCAN CONTROLLING FLAGS
 Although there is normally only one 
output file-spec, sometimes multiple output specs are quite valid.  Also,
many programs do not care if a switch associated with one side of the "=" actually appeared on the other side.  To
allow either (or both) of these special cases, flags are passed to TSCAN which control the scanning process.  These
flags are  also listed in Appendix D ("SCNMAC"):
.skip 1
.indent 5;>FS.MOT -
Multiple output file specifications allowed.
.lm 15
.indent -9
>FS.MIO -
Input and Output specifications may be mixed on the
command line, regardless of their relationships
position-wise to the "=" character.
.skip 1
.LM 1
.hl1 SWITCH PROCESSING
 Finally, it is sometimes the case that 
the user wants to be called whenever a switch value is to be stored, no matter
how it was defined in SWTCHS.  To do this, TSCAN is pointed at the routine to do this.  When this routine is called,
the following are set up:
 
.TEST PAGE 2
.LM10
.ski 1
T1 = switch-value
.break
T2 = pointer into switch tables
.break
.ski 1
.TEST PAGE 2
.LM1
The routine, after doing what it may, non-skip returns if SCAN should not store the value, or skip-returns if SCAN
should store it.  In either case, all accumulators are to be left intact.
.test page 30
.break
.hl1 CALLING .TSCAN
 To call TSCAN, one first sets up an 
argument block of the following form:
.ski 2
.test page 30
.break
.LM16
.TEST PAGE 3
.INDENT -12
.skip 1
BLOCK + 0 =  IOWD xxxxxL, xxxxxN
.INDENT -6
+ 1 =
XWD xxxxxD, xxxxxM
.INDENT -6
+ 2 =
XWD 0, xxxxxP
.INDENT -6
+ 3 =
XWD help-type, help-address
.break
; help-type = 0 if none
.break
;           = 1 if string
.break
;           = 2 if subroutine
.break
;if word = -1, use name in
.break
;system table, and call >HELPER
.break
;if (LH) is greater than 77,
.break
;but word is not -1, then word
.break
;is the SIXBIT name to give >HELPER.
.break
.break
.INDENT -6
+ 4 =
(LH) 0 or routine to clear all answers
.break
(RH) 0 or routine to clear file answers
.INDENT -6
+ 5 =
(LH) routine to allocate input file area
.break
(RH) routine to allocate output file area
.INDENT -6
+ 6 =
(LH) 0 or routine to memorize defaults
.break
(RH) 0 or routine to apply defaults
.INDENT -6
+ 7 =
(LH) 0 or routine to clear defaults
.break
(RH) flags:
.break
.noautopar
       1B18 multiple output specs are legal
.break
       1B19 switches may go anywhere on the line
.break
.INDENT -7
+ 10 =
(LH) 0 (reserved for future)
.break
(RH) 0 or routine to store switch values
.break
.LM1
.test page 15
.break
.SKIP 3
When "0" is given as an argument, then that option will not be used.
The "xxxxx" fields are from the DOSCAN argument.  To call TSCAN:
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
 
.LM6
.ski 1
MOVE T1, [LENGTH,, BLOCK]
.break
PUSHJ P, .TSCAN_#_#
.break
###-return- at end of line after
.break
############something was typed
.bre
.ski 1
.LM1
.TEST PAGE 2
.autopar
.hl1 STORAGE INITIALIZATION
 When TSCAN returns, all of the switches 
and file-specs have been processed, and all values stored.
All switch value cells should have an initial value of -1.  This is because SCAN will detect
attempts to give a switch more than one value on the same line.  Unless a user routine intervened, the first value
would be lost.  If the user wants this -- multiple values -- then the switch must have a routine to do the
storing itself.  In any event, -1 was chosen as an unlikely switch value, and therefore a reasonable initial value.
.ski 1
.TEST PAGE 2
N.B.:  Read Appendix "A" ("Notes on Using SCAN")
.hl1 SUMMARY
 This chapter has presented the use of SCAN's most often used
scanner - .TSCAN.  Much of what has been covered is relevant
not only to .TSCAN, however, but also to the other scanners
being discussed in the following chapters.
.CHAPTER OSCAN - THE OPTIONS FILE SCANNER
.LM1
.ski 1
.hl1 >OSCAN - The Options File Scanner
.index options scanner
.ski2
 It is often the case that a particular application has a set of defaults that change somewhat from user to user.
In this case, it is not possible to define the defaults via DM, since each user has his own, but they all run the
same program.  A solution which is particularly useful is called an "Options File."##This is a single file, under
the user's PPN, which contains the default switch settings for that user.  Since this is feasible for many
programs, all use the same file, but preface their particular lines of defaults with their names.  Finally, it is
possible for one program to have multiple, named, sets of defaults.
.ski 1
.TEST PAGE 2
.hl1 FORMAT OF THE OPTIONS FILE
 This "Options File" is the file DSK:SWITCH.INI, 
on the user's PPN.
Entries in SWITCH.INI are of the form:
 
.TEST PAGE 3
.LM9
.ski 1
Program /SWITCH/SWITCH...
.INDENT -3
######or
.break
PROGRAM:OPTION /SWITCH/SWITCH
.ski 1
.RM 65
where:
.ski 1
.LM17
.INDENT -8
PROGRAM
is the program name.
.INDENT -8
OPTION
is the name of the set of defaults.  This used as the value to the /OPTION: switch in the command line.
.INDENT -8
/SWITCH
are the switches and their values.
.ski 1
.LM1
.RM 65
.TEST PAGE 2
Only switches are valid in the options file -- file-specs cannot be included.
.ski 1
.TEST PAGE 2
.hl2 Options List
 Only one calling parameter for OSCAN 
has not been covered already under "TSCAN" -- the name(s) of options
to select.  The program passes to OSCAN:  
1) the pointer to a list of options to be selected, or 2) the name to be selected, or 3) 0 to imply the use of
the program's name as the object of the selection.
.ski 1
.TEST PAGE 30
.break
.hl2 Argument Block
The argument block for OSCAN closely resembles that for TSCAN:
.skip 3
.LM16
.TEST PAGE 3
.INDENT -12
BLOCK + 0 =
IOWD xxxxxL, xxxxxN
.INDENT -6
+ 1 =
XWD xxxxxD, xxxxxM
.INDENT -6
+ 2 =
XWD 0, xxxxxP
.INDENT -6
+ 3 =
HELP WORD
.INDENT -6
+ 4 =
OPTIONS WORD:
.break
SIXBIT/NAME/####or
.break
Z###############or
.break
XWD###LEN,##LIST
.break
.LM1
LENGTH==.-BLOCK
.ski 3
.LM13

.INDENT -7
LIST:  SIXBIT/OPT1/
.break
SIXBIT/OPT2/
.break
###.
.break
###.
.break
###.
.break
SIXBIT/OPTn/
.bre
.indent -7
LEN==.-LIST
.ski 3
.LM1
.TEST PAGE 4
.HL2 CALLING .OSCAN
.BREAK
 To call OSCAN:
.ski 1
.LM6
.break
MOVE T1, [LENGTH,,BLOCK]
.break
PUSHJ P, .OSCAN_#_#
.break
.ski 1
.LM1
.TEST PAGE 2
.hl1 APPLYING DEFAULTS FOR .OSCAN
 After OSCAN returns, it is usually necessary 
to have the switches applied to any file-specs which were scanned off
by TSCAN (or VSCAN).  This is the purpose of .OSDFS, which is called in the following manner:
.ski 1
.LM6
.break
MOVEI T1, location of Scan-Block
.break
MOVEI T2, length of Scan-Block
.break
PUSHJ P, .OSDFS_#_#
.break
.ski 1
.LM1
.TEST PAGE 2
Once this has been done for any or all file-specs desired, the scanning process is complete.
.CHAPTER _.VSCAN - THE VERB FORM SCANNER
.LM1
.ski3
.hl1 >VSCAN - The Verb Form Scanner
.index verb form scanner
.ski3
 In some applications, it is desirable to have all command lines begin with a keyword which indicates
some function or operation to be performed.  This is then followed on succeeding lines by related commands and file-specs.  In this case, the
function-word is referred to as a "verb," and the associated scanner is therefore a "verb form scanner," or ".VSCAN."
 Normally, when VSCAN is used, the user 
enters his switches one-per-line.
Although SCAN views these as switches no differently than it does with TSCAN,
it appears to the user that he is actually inputting commands; this
is especially true since it is not necessary with VSCAN to include
the slash that normally indicates a switch.  In some applications, this lends
itself very well to user oriented dialogues.
While it would be possible for switches to appear on the line with the
"verbs," this would tend to contradict the philosophy behind
using VSCAN in the first place.
.TEST PAGE 2
.hl1 USING .VSCAN
 From the programmer's point of view, 
there is really nothing new for
VSCAN that was not also necessary for TSCAN.
.ski 1
.TEST PAGE 2
 The only new calling values in the argument block are the addresses and lengths of the default and
permanent switch areas for file-specs (a la P.ZER and F.ZER, respectively).
.hl2 Argument Block Format
 The exact argument block format for VSCAN is:
.ski 1
.TEST PAGE 3
.LM13
.INDENT -12
BLOCK + 0 =
IOWD xxxxxL, xxxxxN
.INDENT -6
+ 1 =
XWD xxxxxD, xxxxxM
.INDENT -6
+ 2 =
XWD 0, xxxxxP
.INDENT -6
+ 3 =
HELP WORD
.INDENT -6
+ 4 =
(LH) length of file-spec areas
.break
(RH) address of permanent area
.break
.INDENT -6
+ 5 =
(LH) 0 (reserved for future)
.break
(RH) address of default area
.break
.INDENT -6
+ 6 =
OPTION NAME, or 0 (to use program name)
.LM1
LENGTH==.-BLOCK
.ski 1
.LM1
.TEST PAGE 3
.HL2 CALLING .VSCAN
.BREAK
 The VSCAN call is:
.ski 1
.LM6
.break
MOVE T1, [LENGTH,,BLOCK]
.break
PUSHJ P, .VSCAN_#_#
.break
.CHAPTER _.PSCAN - THE PARTIAL SCANNER
.break;.subtitle PSCAN _& QSCAN - INTRODUCTION
.INDEX PSCAN
.INDEX .PSCAN
.INDEX QSCAN
.INDEX .QSCAN
.INDEX PARTIAL SCANNER
.PAGE
.hl1 PSCAN _& QSCAN - INTRODUCTION
 One of the drawbacks, in some applications, of having an
all purpose scanner such as TSCAN is that it does not
allow any flexability in the format of the command lines.
ALL commands must conform to the sytax used by SCAN.  Usually, this
presents no problem, since SCAN's syntax is in itself quite
flexable.  However, when it is necessary for the format of a
command line to be somewhat different, then another
scanner is required.  This is the usefulness of the so called
"Partial Scanner."  This scanner tends to operate as a co-operative effort
between the user program and SCAN.  
Part of the command line is processed by the program, and the
remainder is processed by .PSCAN or .QSCAN.
 The process is simple.  Either .PSCAN or .QSCAN is called
to initialize the scanning process, then the user program
processes the command line to whatever extent it desires.
 The routine which is normally called to handle SCAN's side of
the command line handling is ".FILIN", which will pick up
any file specifications, as well as whatever switches it
encounters.  This makes for a relatively simple scanning process:
.list 1,'o'
.le
Call .ISCAN to initialize everything
.le
CALL .PSCAN to initialize for partial scanning (or .QSCAN)
.le
Call whatever input routines are appropriate for the user's
portion of the command line (.SWDEC, .SWSIX, etc.).
.le
Call .FILIN to handle the rest of the command line
.le
Process the SCAN-blocks, if any, which were generated
by .FILIN.
.le
Process the data returned by the switches scanned off by .FILIN
.end list
.hl1 PSCAN vs QSCAN
 Throughout the discussion so far, two routines have been
referred to as the partial scanners -- .PSCAN _& .QSCAN.
These operate in identical fashions, so far as use within
a program is concerned.  Their only difference lies in their
scope.  .PSCAN sets up partial scanning on a global basis, which
affects as input lines.  .QSCAN, on the other hand, affects only the current
line.  Other than this, they are used identically.
.hl1 SUMMARY
 The purpose of this chapter has been to introduce the concept of a
partial scanner, which is sometimes very well suited for
a particular application.  In addition, instruction on using
the two routines supplied by SCAN -- .PSCAN and .QSCAN --
to handle this type of scanning has been given.  An excellant
example on the use of partial scanners is the Digital CUSP
CREDIR.
.index CREDIR
A part of this program, in fact, is included in a later chapter as a guide in writing programs
which interface with SCAN.
.CHAPTER ACCESSING SCAN
.flag capital
.LM1
.ski3
.hl1 ACCESSING SCAN
.index acessing scan
.hl2 ASSEMBLY TIME FILES
 All of the MACROS, symbols and routine 
names referenced in this document are a part of SCAN and its associated files.
The following files are those used in the SCAN "system."
 
.list 1,'o'
.le
UUOSYM.UNV
.break
MACTEN.UNV
.SKIP 1
These define symbols used in the DEC reference manuals  to describe UUOs and their calling formats.  Also defined are useful
macros,  such as:  POINTR, TXxx, MOVx, etc.
.skip 1
These are accessed by the MACRO-10 statement:
.skip 1
.indent 10
SEARCH UUOSYM,MACTEN
.le
SCNMAC.UNV
.break
_$SCNDC.UNV
.skip 1
These files define macros and symbol
definitions for SCAN.
SL, SN, SP, SS, DM, KEYS, DOSCAN,  etc,  are all defined here
.INDEX DOSCAN MACRO
.INDEX SL
.INDEX SN
.INDEX SP
.INDEX SS
.INDEX DM MACRO
.INDEX KEYS KEYS
.INDEX MACROS - DOSCAN
.INDEX MACROS - KEYS
.INDEX MACROS - SL
.INDEX MACROS - DM
.INDEX MACROS - SS
.INDEX MACROS - SN
.INDEX MACROS - SP
.skip 1
SCNMAC and _$SCNDC are accessed by the MACRO-10 statement:
.skip 1
.indent 10
SEARCH SCNMAC,_$SCNDC
.END LIST
.hl2 LINK-TIME FILES
.list 1,'o'
.le
SCAN.REL
.skip 1
This is SCAN itself.  Contains all code described herein, including _$SCNDC.  SCAN.REL should be loaded in library
search mode.
.skip 1
.test page 15
.le
>HELPER.REL
.skip 1
This is a module for the /HELP switch, and is loaded as any other file.
.skip 1
.end list
.TEST PAGE 20
.autopar
.hl2 SOURCE FILES
 Sources to SCAN, SCNMAC, HELPER,
MACTEN and UUOSYM
are currently distributed on the CUSP release tapes as:
.skip 1
.LM12
SCAN.MAC
.break
SCNMAC.MAC
.break
HELPER.MAC
.break
MACTEN.MAC
.BREAK
UUOSYM.MAC
.break
.skip 1
.LM1
Parts of _$SCNDC and SCNMAC have been included as appendices D and E respectively.
 The universal (.UNV) files for <SCNMAC, <_$scndc, <macten and
<uuosym are normally kept on ersatz device "<unv:."
The .<rel files for <scan, <wild, and <helper are usually on device "<rel:."
.skip 1
.TEST PAGE 2
.HL2 SUMMARY
.BREAK
 In summary, the following would normally 
be seen at the start of a program using SCAN:
.noautopar
.skip 1
	SEARCH COLS,C,SCNMAC,_$SCNDC
.break
	.REQUEST REL:SCAN
.BREAK
	.REQUEST REL:WILD
.BREAK
	.REQUEST REL:HELPER
.TEST PAGE 20
.autopar
.LM1
.hl1 SEGMENT ALLOCATION
 All of the code in SCAN is high segment; no .LOW file will be generated unless the user's program needs one.
As a general rule, when using the standard DEC SCAN,
if any calling routine is in the low-segment, then the linked files should not be protected as
"execute only" (i.e.: 166).  This is because SCAN does not include PORTAL instructions at its entry points.
All of the entries in the modified version of SCAN, however,
do contain PORTALs, and may be entered from low
segments as an execute only high segment.
.chapter EXAMPLE OF USING SCAN
.break;.subtITLE Partial Scanning -- CREDIR
.page
.hl1 INTRODUCTION
 This chapter will  present two complete  examples
of using SCAN for command scanning.  It will use much
of the material presented in previous chapters.  The
basic purpose in this is to unite the concepts and
routine descriptions presented into a cohesive
structure.
 The first example chosen is from CREDIR, a Digital CUSP used
to create directories on TOPS-10 systems.  The scanners
used are the Partial Mode scanners, .PSCAN _& .QSCAN.
 A second example, from a private program, will present
a use of .TSCAN, which is by far the most popular scanner.
By examining closely both examples, the reader
should gain a detailed understanding of the use of
SCAN.
.SUBTITLE EXAMPLE:  CREDIR (.PSCAN/.OSCAN)
.page
.nofill
.nojust
.noautopar
.noflag capital
.noflag index
.index EXAMPLE - CREDIR
.INDEX CREDIR
.INDEX PSCAN
.INDEX .PSCAN
.INDEX QSCAN
.INDEX .QSCAN
TITLE	CREDIR -- ROUTINE TO CREATE A DIRECTORY  %2(103)
	SEARCH	C,SCNMAC	;SET FOR UNIVERSALS
	SUBTTL	INITIALIZATION
.skip 1
CREDIR:	TDZA	T1,T1		;NOT CCL START
	MOVEI	T1,1		;CCL START
	MOVEM	T1,OFFSET	;STORE IT
.skip 1
	RESET			;RESET ANY EXTERNAL I/O
.skip 1
;NEXT GO INITIALIZE THE COMMAND SCANNER.  IN
;PARTICULAR, LOOK FOR A COMMAND ON THE SAME LINE OR A CCL
;FILE FULL OF COMMANDS.
.skip 1
	MOVE	T1,[ 2,,[IOWD  1,['CREDIR']
			OFFSET,,'CRR']]
	PUSHJ	P,.ISCAN_#_#	;INITIALIZE COMMAND SCANNER
.skip 3
	SUBTTL	MAIN LOOP
.skip 1
;EACH PASS, WHETHER SUCCESSFUL OR NOT, ALWAYS
;ENDS BY RETURNING TO THE LABEL MAINLP.  THIS CAUSES THE
;PROGRAM TO START OVER AGAIN.  IT CAN BE EXITED BY THE
;USER BY EITHER A _^C OR A _^Z.  IF THE PROGRAM HAD BEEN
;INVOKED BY  A COMMAND OR CCL CALL, THEN SCAN WILL
;SIMULATE THE _^Z WHEN APPROPRIATE TO EXIT.
.skip 1
MAINLP:	PUSHJ	P,.RUNCM_#_#	;HANDLE /RUN IF SET
.skip 1
	MOVE	T1,[ 4,,[IOWD SWTL,SWTN
			 SWTD,,SWTM
			 0,,SWTP
			 -1	]]
	PUSHJ	P,.PSCAN_#_#	;INVOKE P-MODE SCANNER
	  OUTSTR [ASCIZ _\Create directory: _\]
.skip 1
	CAMG	P4,[.CHEOF]	;SEE IF EOF
	JRST	[PUSHJ P,.ALDON_#_#  ;YES--HANDLE NORMAL CASES
		 CAMG  P4,[.CHEOF] ;THEN CHECK AGAIN
		 PUSHJ P,.MNRET_#_#  ;YES--RETURN TO MONITOR
		 JRST  MAINLP]	;THEN START OVER AGAIN
.page
;HAVING INITIALIZED THE COMMAND SCAN FOR THIS LINE,
;NOW GET A FILE SPECIFICATION, WHICH MUST INCLUDE
;THE STRUCTURE AND DIRECTORY AND EXCLUDE THE FILE NAME AND
;EXTENSION.
.skip 1
	PUSHJ	P,.FILIN_#_#	;GET FILE SPEC
	JUMPN	T1,GETOPT	;JUMP IF SOMETHING INPUT
.skip 1
;HERE IF NOTHING TYPED BEFORE THE SEPARATOR.  THE ONLY
;LEGAL CASES ARE /RUN AND INDIRECT.
.skip 1
	CAIN	P4,"@"		;SEE IF INDIRECT
	PUSHJ	P,.GTIND_#_#	;YES--SETUP INDIRECT
	JUMPLE	P4,MAINLP	;IF END OF LINE, GO DO MORE
	PJRST	E.ILSC_#_#	;OTHERWISE, GIVE ERROR
.skip 1
;NOW CHECK OPTION FILE TO SEE IF ANY DEFAULT SWITCHES.
.skip 1
GETOPT:	JUMPG	P4,E.INCL_#_#	;ERROR IF MORE ON LINE
	MOVEI	T1,SPEC		;POINT TO SPEC AREA
	MOVEI	T2,.FXLEN	; ..
	PUSHJ	P,.GTSPC_#_#	;COPY TO US
.skip 1
	MOVE	T1,[ 4,,[IOWD SWTL,SWTN
			 SWTD,,SWTM
			 0,,SWTP
			 -1	]]
	PUSHJ	P,.OSCAN_#_#	;HANDLE OPTION FILE
	JRST	GOTSOM		;THEN PROCEED
.page
;DEFINE SWITCH TABLE
.skip 1
DEFINE	SWTCHS,_<
SP IN,QTAIN,.SWDEC_#_#,QTA,FS.LRG
SP NAME,SPLNAM,SIXQWW,NUL,
SP OUT,QTAOUT,.SWDEC_#_#,QTA,FS.LRG
_>
.skip 1
DM NUL,1,0,0
DM QTA,.INFIN,.INFIN,.INFIN
.skip 1
	DOSCAN	(SWT)
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
.skip 3
;ROUTINE TO INPUT ONE WORD IN SIXBIT POSSIBLY QUOTED
.skip 1
SIXQWW:	PUSHJ	P,.SIXQW_#_#	;GET STRING
	MOVE	P3,.NMUL_#_#	;GET FIRST WORD
	POPJ	P,		;RETURN RESULT
.skip 3
GOTSOM:	SKIPE	T1,FLDIAL	;SEE IF DIALOG
	SKIPL	SPEC+.FXMOD	;SEE IF DEVICE THIS TIME
	SKIPA			;OK--DO NOTHING
	MOVEM	T1,SPEC+.FXDEV	;LAZY--DEFAULT HIS DEVICE
;fall into other code not of interest in
;this example case.
.page
GOTDIR:	MOVX	T1,FX.PRO	;GET PROTECTION MASK
	TDNN	T1,SPEC+.FXMOM	;SEE IF USER SET IT
	SKIPN	FLDIAL		;OR NOT IN DIALOG
	JRST	GOTDR1		;ALL OK--PROCEED
.skip 1
	MOVE	T1,[ 4,,[0
			 0
			 0
			 -1	]]
	PUSHJ	P,.QSCAN_#_#	;INVOKE P-MODE SCANNER
	  OUTSTR [ASCIZ _\Protection: _\]
	PUSHJ	P,.OCTNW_#_#	;GET OCTAL VALUE
	DPB	P3,[POINTR (SPEC+.FXMOD,FX.PRO)]
	JUMPG	P4,E.INCL_#_#	;ERROR IF MORE ON LINE
.skip 1
GOTDR1:	SKIPGE	SPLNAM		;SEE IF /NAME
	SKIPN	FLDIAL		;NO--SEE IF DIALOGUE
	JRST	GOTDR2		;YES--PROCEED
	MOVE	T1,[ 4,,[0
			 0
			 0
			 -1	]]
	PUSHJ	P,.QSCAN_#_#	;INVOKE P-MODE SCANNER
	  OUTSTR [ASCIZ _\Name: _\]
	PUSHJ	P,SIXQWW	;GET SIXBIT NAME
	JUMPG	P4,E.INCL_#_#	;ERROR IF THAT'S NOT ALL
	MOVEM	P3,SPLNAM	;SET NAME
.skip 1
GOTDR2:	MOVS	T2,SPEC+.FXEXT	;GET EXTENSION
	TLC	T1,-1		;MASK SHOULD BE -1
	CAIE	T1,'UFD'	;SEE IF UFD
	CAIN	T1,'SFD'	; OR SFD
	SETZB	T1,SPEC+.FXEXT	;YES--CLEAR OUT
	SKIPN	SPEC+.FXNAM	;SEE IF FILE NAME
	SKIPE	SPEC+.FXEXT	; OR EXTENSION
	JRST	E_$_$FNI		;YES--FILE NAME ILLEGAL
.skip 1
	MOVEI	T1,SPEC		;POINT TO SCANNED SPEC
	MOVEI	T2,OPNBLK	;POINT TO AN OPEN BLOCK
	MOVEI	T3,ENTBLK	;POINT TO AN ENTER BLOCK
	PUSHJ	P,.STOPN_#_#	;CONVERT SCAN'S SPEC
	  JRST	E_$_$WCI		;WILD CARDS ARE ILLEGAL
	JRST	DEVOK		;PROCEED
.skip 1
;fall into code which does actual processing of directories,
;etc., which is of no concern here as a SCAN example.
.autopar
.fill
.just
.flag capital
.flag index
.break;.subtitle TSCAN Example
.page
 The next example, of the use of TSCAN, is from a program
written to count the number of form-feeds in an arbitrary
set of files.  No switches are used, but a dummy SWTCHS
definition is used to keep TSCAN happy.  The inclusion of
additional switches would be trivial.  The important parts to
watch are the interfacing with TSCAN, and the processing
of the SCAN blocks.  The actual use of the converted OPEN and
LOOKUP/ENTER blocks is left out.
.page
.noautopar
.nofill
.nojust
.noflag capital
.noflag index
.NOFILL
.NOJUST
.NOAUTOPAR
.NOFLAG CAPITAL
.NOFLAG INDEX

TITLE	FINDFF - FIND NUMBER OF FORM-FEEDS IN GROUP OF FILES
	.REQUEST SCAN
	.REQUEST WILD
	SEARCH	UUOSYM,SCNMAC,_$SCNDC
.skip 1
;*************************************************
; INITIALIZATION ROUTINE
;*************************************************

FINDFF:	RESET
	MOVE	P,[IOWD PDLSIZ,PDL]
	MOVEI	T1,1
	MOVEM	T1,TOTFF	;STARTS AT 1 PAGE (NO INITIAL FF)
	MOVE	T1,[ISCLEN,,ISCBLK]
	PUSHJ	P,.ISCAN_#_#	;INITIALIZE SCAN
	PUSHJ	P,.TCRLF_#_#
	SETZM	WILDSW		;INDICATE NO WILD SPEC IN FORCE
.skip 1
;*************************************************
; ROUTINE TO GET NEXT FILE SPECIFICATION FROM SCAN
;*************************************************
.skip 1
GETNAM:	SKIPE	WILDSW		;SKIP IF NO WILD SPEC IN FORCE
	JRST	CALWLD		;JUMP IF A WILD SPEC IS CURRENT
.skip 1
GETSPC:	MOVE	T1,[XWD P.ZER_#_#,P.ZER_#_#+1]
	SETZM	P.ZER_#_#
	BLT	T1,P.EZER_#_#	;INIT DEFAULT REGION FOR .TSCAN
	MOVE	T1,[TSCLEN,,TSCBLK];ARGUMENT BLOCK
	PUSHJ	P,.TSCAN_#_#	;GET NEXT FILE SPECIFICATION 
				;FROM INPUT SOURCE
	SETOM	WILDSW		;REMEMBER THAT A WILD 
				;SPEC IS CURRENT
	HLLZS	WLDBLK+3	;CLEAR WILD'S POINTER
	SETZ	0,		;FIX WILD BUG WHICH CLOBBERS 0
.skip 1
CALWLD:	MOVEI	T1,[SCNBLK]	;RESET SCAN BLOCK ADDRESS IN CASE
	HRLM	T1,WLDBLK	;WE ALREADY CALLED .LKWLD BEFORE,
.skip 1
	MOVE	T1,[OPNBLK,,LKPBLK]
	MOVEM	T1,WLDBLK+1	;FIX WILD BUG WHICH CLOBBERS
	MOVE	T1,[WLDLEN,,WLDBLK]	;THIS WORD
	PUSHJ	P,.LKWLD_#_#	;GET NEXT FILE NAME FROM WILD SPEC
	JRST	GETSPC		;HERE WHEN DONE WITH WILD SPEC
	POPJ	P,
.page
;*************************************************
; PROMPT ROUTINE FOR GETFIL
;*************************************************
.skip 1
PROMPT:	MOVEI	T1,[ASCIZ /FILE: /]
	PUSHJ	P,.TSTRG_#_#	;TYPE STRING
	POPJ	P,
.skip 2
;*************************************************
; ROUTINE TO ALLOCATE OUTPUT FILE SPACE FOR SCAN
;*************************************************
.skip 1
GETOUT:	MOVE	T1,[XWD SCNBLK,SCNBLK+1]
	SETZM	SCNBLK
	BLT	T1,SCNBLK+SCNLEN-1
	MOVEI	T1,SCNBLK
	MOVEI	T2,SCNLEN
	POPJ	P,
.page
;***********************************************************
; DEFINITIONS AND WORKAREAS NEEDED BY SCAN AND WILD
;***********************************************************
.skip 1
_.HELPR==:.TCRLF_#_#		;ELIMINATE LINK10 DIAGNOSTIC
.skip 1
ISCBLK:	Z			;SCAN INITIALIZATION BLOCK
	Z
	Z			;DEFAULT TTY I/O ROUTINES ARE TTCALLS
	Z
	XWD	PROMPT,MONRET	;PROMPT ROUTINE,,MONITOR RETURN
				;ROUTINE
	Z
ISCLEN=.-ISCBLK
.skip 1
SCNBLK:	BLOCK	20		;COPY SCAN BLOCK INTO HERE
SCNLEN=.-SCNBLK
.skip 1
WLDBLK:	XWD	[SCNBLK],0	;SCAN-BLOCK POINTER
	XWD	OPNBLK,LKPBLK	;OPEN AND LOOKUP BLOCKS
	XWD	SCNLEN,LKPLEN	;LENGTHS OF SCAN BLOCK 
				;AND LOOKUP BLOCK
	EXP	1B0		;ALLOW ANY DEVICE
	EXP	.POPJ_#_#		;NO ROUTINE TO CALL AT END OF UFD
WLDLEN=.-WLDBLK
.skip 1
DEFINE	SWTCHS_<
SP	FOO,FOOLOC,.SIXSW_#_#,,,0	;DUMMY SWITCH FOR .TSCAN
_>
.skip 1
DOSCAN	(FOO)
.INDEX MACROS - DOSCAN
.INDEX DOSCAN MACRO
.skip 1
TSCBLK:	IOWD	FOOL,FOON	;ARGUMENT BLOCK FOR TSCAN
	XWD	FOOD,FOOM
	XWD	0,FOOD
	Z
	Z
	XWD	GETOUT,GETOUT
	Z
	Z
	Z
TSCLEN=.-TSCBLK
.skip 1
FOOLOC:	Z
.AUTOPAR
.FILL
.JUST
.FLAG CAPITAL
.FLAG INDEX
.autopar
.flag capital
.spacing 1
.chapter USING THE MISCELLANEOUS ROUTINES
.hl1 INTRODUCTION
.BREAK
 The purpose of this chapter is to highlight the uses
of some of the miscellaneous routines in SCAN.  These
are routines that are not directly related to the task
of scanning command lines, but which often make writing
programs simpler.  The initial chapter, which listed the routines
in SCAN, gave an adequate description of the Input and Output
routines, which will not be covered here.
.hl1 #.LKNAM
.break
.index .LKNAM
 This routine is used to perform the commonly needed
task of table searching.  It is, in fact, the routine
which the command scanners themselves use to lookup switch
and command names.  The argument, which must be in SIXBIT
(like the table being searched),  can be an abbreviation of
an entry in the table.  Exact matches will always be found, even
if they constitute an abbreviation for another command.
The lookup attempt into the table will fail for one of two reasons:
1) no match or abbreviation was found at all, or 2) more than
one abbreviation, and no exact match, was found.
 The call on .LKNAM is as follows:
.skip 1
.indent 10;MOVE T1,[IOWD len,address]
.indent 10;MOVE T2,[SIXBIT/mumble/]
.indent 10;PUSHJ P,.LKNAM_#_#
.INDENT 10;#-here if failure-
.indent 10;#-here if success-
.skip 1
.test page 10
.break
where:
.indent 10;len#####is the length of the table
.indent 10;address#is the address of the table
.indent 10;mumble##is the word being searched for
.skip 1
On the failure return:
.skip 1
.indent 10;T1_<0 if no match was found
.indent 10;T1_>0 if multiple abbreviations were found
.skip 1
On success return:
.skip 1
.indent 10;T1_<0 if exact match was found
.indent 10;T1_>0 if abbreviation was found
.indent 10;(RH) of T1 = address of table entry matched
.skip 1
.hl1 DATE AND TIME CONVERSION
.break
 Since the conversion between Universal Date/Time
and the DEC standard format is complex, a routine is
provided within SCAN to perform this function.
The Universal format contains the date in the left half, and the time
in the right half.  The DEC standard Format contains the date
(derived in a different manner) in one word, and the time (also of
a different derivation) in another unrelated word.
Three routines are provided to handle these functions:
.list 1,'o'
.le
#.CNTDT - convert from Universal to DEC
.le
#.CNVDT - convert from DEC to Universal
.le
#.GTNOW - get the current time in Universal format
.end list
.hl2 #.CNTDT
.break
 To convert from universal format to <dec format, use
the following calling specification:
.skip 1
.indent 10;MOVE T1,universal date-time
.indent 10;PUSHJ P,.CNTDT_#_#
.INDENT 10;#-always returns here-
.skip 1
.test page 10
.break
.indent 10;with T1=time as MS past midnite
.indent 10;#and T2=DEC format date
.hl2 #.CNVDT
.break
 This routine converts from DEC format to Universal format.
The calling sequence for it is:
.skip 1
.indent 10;MOVE T1,time
.indent 10;MOVE T2,date
.indent 10;PUSHJ P,.CNVDT_#_#
.INDENT 10;#-always returns here-
.skip 1
where
.indent 10
"time" is the time in milleseconds past midnite
.indent 10;"date" is the date in DATE UUO format
.skip 1
On return,
.skip 1
.indent 10;T1=Universal date/time, or
.indent 10;T1=-1 if arguments were past Sept. 27,2217
.skip 1
An advantage of the Universal format is the ease of converting
from date to day of week.  The base for the Unviersal system,
also referred to as the Astronomical Standard, was a Wednesday.
Therefore, dividing the Universal date by seven yields a remainer
that indicates the day of the week.  Zero would be a Wednesday,
and the others fall in sequence.
.hl2 #.GTNOW
.break
Since the only method of finding the current Universal date/time
from the monitor if via a GETTAB, life is made a little simpler by
using this routine.  It takes no arguments, and simply returns
the current date and time in universal format, in T1.
.hl1 MANIPULATING LISTS OF DATA
.break
 SCAN provides two routines useful when a list of data
must be manipulated in a sequential fashion.  One routine is
used to remove a data word from the list, another to place data
into the list.
 The accumulator usage for these routines is a follows:
.list 1,'o'
.le
T1 is the current address in the list
.le
T2 is the number of words left in the list
.le
T3 is the data being manipulated.
.end list
 To place data into the list, .PTWRD is called in the
following manner:
.skip 1
.indent 10;MOVE T1,address
.indent 10;MOVE T2,length
.indent 10;MOVE T3,datum
.INDENT 10;PUSHJ P,.PTWRD_#_#
.INDENT 10;#-always returns here-
.skip 1
with
.skip 1
.indent 10;T1#incremented to the next list address
.indent 10;T2 decremented by 1
.indent 10;T3 contains the old data item
.skip 1
 To remove an item from the list, .GTWRD is called
in a similar fashion:
.skip 1
.indent 10;MOVE T1,address
.indent 10;MOVE T2,length
.indent 10;PUSHJ P,.GTWRD_#_#
.indent 10;#-always returns here-
.skip 1
with
.skip 1
.indent 10;T1 incremented by 1 to the next location
.indent 10;T2 decremented by 1
.indent 10;T3 data item, or
.indent 10;###zero if nothing left in list (T2_<=0)
.skip 1
Note that since the routines automatically update their
pointers, the setup need only be done for the first usage
of the routines.  After that, they can be called
successively to remove  arguments (or whatever) from a list,
and to place return values (or whatever) into the list.
.noflag capital
.appendix NOTES ON USING THE SCANNERS
.skip 10
.center
APPENDICES
.skip 10
.LM1
A.   NOTES ON USING THE SCANNERS
.BREAK
B.   NOTES ON USING WILD
.BREAK
C.   DIFFERENCES BETWEEN DEC AND OLS
.BREAK
####SCAN AND WILD
.BREAK
D.   SCNMAC - COMMAND SCANNER MACROS
.BREAK
E.   _$SCNDC - COMMAND SCANNER DECLARATIONS
.BREAK
F.   EXAMPLE:  SCAN
.break
G.   EXAMPLE:  ALKFIL
.break
H.   LIST OF CUSPS AND THE SCANNERS WHICH
.break
####THEY USE
.page
.skip 5
.list 1,"o"
.le
When supplying a user-written character input routine, the character must be returned in P4.  No other accumulator should be 
altered.
 
.le
When supplying a user-written routine for processing a switch, SCAN will call it via a PUSHJ, with P1 containing the index 
into the tables generated by DOSCAN for the switch being processed.  If it is desired that SCAN store the
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
value, then the routine must leave the value in P3, and take a skip-return.  A non-skip return to SCAN is an indication
that SCAN should not store a value.
 
.le
Initial values of the locations into which SCAN stores switch values should be -1.
 
.le
The maximum value handled by DM is 3777777; the minimum is 0.  If these are not suitable for a switch, then define
the appropriate symbols before calling DM.
 
.TEST PAGE 2
.le
SCAN will generate a reference to the external symbol ".HELPR".  This is normally resolved by loading REL:HELPER.REL,
and is used for processing the /HELP switch.  However, if no help processing is to be done, then the following is
sufficient:
.skip 1
.center
#.HELPR==:.TCRLF_#_#
.end list

.appendix NOTES ON USING WILD
.LM1
.skip 5
.index Using Wild
 For the most part, WILD is well documented in its write-up in the Software Notebooks.  However, there are a few
things to be aware of.
 
.lm 3
.list 1
.le
WILD has a bug which clobbers AC0 in a very orderly fashion;  
try to keep your own AC0 safe.
 
.le
Because of the nature of _#1, if multiple top-level calls to WILD are made (i.e.:  multiple wild card specs
not scanned off together), then WILD, after completely expanding the first spec, will forever after think
it is done.  This is because AC0 is clobbered to a file-spec pointer, later to something else, and then even later
looked at in the context of a file-spec pointer.  The "fix" is a simple SETZ of AC0 before each top-level call
to .LKWLD is started.
 
.le
The documentation says that .LKWLD only needs to be given the address of its argument block.  WRONG!  Like almost
all other code, it expects to see a length in the left half of T1.
 
.le
For an unknown reason, WILD will, on occasion, write into part of its argument block, usually to the OPEN block and
LOOKUP block pointers.  Beware.
.end list
.lm 1
.ski5
.LM1
.test page 5
.break
 The following subroutines are also documented in the Software Notebooks, but are included here for added exposure.
To type a standard LOOKUP or ENTER error message,  the following routines are quite useful:
.test page 10
.break
.skip 1
.list 1,"o"
.le
To type out a message which includes the filename, error code, etc.:
.skip 1
.indent 5;MOVEI T1, address of extended LOOKUP/ENTER block
.indent 5;MOVEI T2, length of LOOKUP block
.indent 5;MOVEI T3, address of SCAN block
.indent 5;PUSHJ P, E.LKEN_#_#
.skip 1
.le
To type out only the code and its meaning (no filename, etc.):
.skip 1
.indent 5;MOVE1 T1, error-code
.indent 5;PUSHJ P, .LKERR_#_#
.end list
.ifnot DEC
.appendix CHANGES MADE TO SCAN _& WILD
.skip 5
.LM1
.center
Differences In SCAN _& WILD Between the
.center
Digital Equipment Corp. Version
.center
and
.center
On-Line Systems, Inc. Version
.index differences - dec/ols
.ski5
 For the most part, no major changes have been made to the DEC released versions.  Some code has been added, and the
characteristics of other code have been slightly altered.  In particular:
.skip 1
.lm 3
.list 1,'o'
.le
Modules for Space Allocation and Random Number Generation have been added to SCAN.
 
.le
The subroutine .TRDXW in SCAN has been fixed to work correctly.  The digits
A,B,C,D,E,F,... used to come out one digit too high (B,C,D,E,F,G,...).
 
.le
Code has been added to save any "T" accumulator into which a value is not being returned.  (DEC clobbered the "T"
accumulators at will, since they were "temporarY").
This makes it simpler to use SCAN with existing software, which
may have a more or less arbitrary set of register conventions.
.le
A number of additional single-character output
routines have been added.  These perform the task of printing
a single special character, in the same way that
_.TCOLN is used to easily print a colon character.  The routines
which have been added are identifiable in the list given earlier
(see Chapter Two) by the asterisk in the outside margin.
.end list
.endif DEC
.lm 1
.appendix SCNMAC:  COMMAND SCANNER MACROS
.LM1
.skip 5
 This is a listing of the contents of SCNMAC.MAC, which is
the file containing most of the MACROS and parameters used
by SCAN's routines.  It is accessed by the 
.skip 1
.indent 10;SEARCH SCNMAC
.skip 1
statement at the beginning of a program using SCAN.
.skip 2
.nojust
.BREAK
.noautopar
.BREAK
.noflag capital
.BREAK
.noflag index
.BREAK
.BREAK
.CENTER 
SCNMAC - COMMAND SCANNER MACROS
.index scnmac
.BREAK
.SKI 3
.BREAK
#	SUBTTL	COMMAND SCANNER MACROS   %7(105)   25-AUG-74
.BREAK
#
.BREAK
#
.BREAK
#;MACRO DEFINITIONS OF GENERAL USE
.BREAK
#
.BREAK
#;DEFAULTS
.BREAK
#
.BREAK
#;DM ABBREVIATION,MAX,ADEFAULT,PDEFAULT
.BREAK
#; DEFINES     SYMBOLS     MX.ABBREVIATION,
.break
#; AD.ABBREVIATION,  AND PD.ABBREVIATION TO
.break
#; BE  THE  MAXIMUM  ALLOWED   VALUE,   THE
.break
#; DEFAULT  IF  THE  KEYWORD IS ABSENT, AND
.break
#; THE DEFAULT IF THE  KEYWORD  IS  PRESENT
.break
#; RESPECTIVELY  UNLESS  THE  CORRESPONDING
.break
#; SYMBOL IS ALREADY DEFINED.
.break
#
.BREAK
#
.BREAK
# DEFINE	DM(ABBR,MAX,ADEF,PDEF),<
.INDEX MACROS - DM
.INDEX DM MACRO DEFINITION
.INDEX DM MACRO
.BREAK
#	ND	MX.'ABBR,MAX
.BREAK
		ND	AD.'ABBR,ADEF
.BREAK
		ND	PD.'ABBR,PDEF>
.BREAK
#
.BREAK
#
.BREAK
#; KEYS (NAME,LIST)   WILL DEFINE A LIST OF KEYS BY NAME NAME
.INDEX KEYS MACRO
.INDEX KEYS MACRO DEFINITION
.INDEX MACROS - KEYS
.BREAK
#;	NAME CAN BE UP TO 4 CHARS.  (DEFINES NAME.T AND NAME.L)
.BREAK
#;	LIST IS SIXBIT NAMES SEPARATED BY COMMAS.
.BREAK
#;	DEFINES NAME CONCATENATED WITH START OF ITEM IN LIST
.BREAK
#;	AS INDEX IN LIST UNLESS THE ITEM BEGINS WITH "*"
.BREAK
#
.BREAK
#
.BREAK
#
.BREAK
#
.break
#
.break
#

#;SWITCH SCANNING  MACROS  AND  TABLES  
.BREAK 
#
.BREAK
#; SWTCHS  IS  THE  MACRO LISTING ALL KNOWN
.INDEX SWTCHS MACRO
.INDEX SWTCHS MACRO DEFINITION
.INDEX MACROS - SWTCHS
.BREAK
#; SWITCHES.  IT  INCLUDES  THE   NAME   AND
.BREAK
#; STORAGE  LOCATION  FOR  VALUE  TYPES, IT
.BREAK
#; ALSO  HAS  THE  MAX  AND   DEFAULT   AND
.BREAK
#; PROCESSOR FOR KEY-VALUE TYPES, IT POINTS
.BREAK
#; TO THE KEYS AND HAS THE DEFAULT  IF  ANY
.BREAK
#; FOR STAND-ALONE TYPES, IT HAS THE VALUE.

#
.BREAK
#;WHEN THE SWITCH SCANNING TABLES ARE TO BE BUILT, INVOKE
.BREAK
#;THE MACRO DOSCAN WITH 5-CHAR ARGUMENT TO USE AS SYMBOL PREFIX
.INDEX MACROS - DOSCAN
.INDEX DOSCAN MACRO
.BREAK
#;IT WILL DEFINE XXXXXN,L,P,M,D
.BREAK
#
.BREAK
.BREAK
# 
.BREAK
.page
.BREAK
#; SL  NAME,STORAGE,TABLE-NAME,DEFAULT,FLAGS
.INDEX SL MACRO
.INDEX SL MACRO DEFINITION
.INDEX MACROS - SL
.BREAK
#;	DEFINES A LIST OF KEY-VALUES (SEE KEYS MACRO)
.BREAK
#;	DEFAULT IS THE ORDINAL OR 0 IF NO DEFAULT
.BREAK
#;	IF LH(STORAGE)=7777B11, STORAGE = ROUTINE TO PROCESS
.BREAK
#;
.BREAK
#; SP  NAME,STORAGE,PROCESSOR,ABBREVIATION,FLAGS
.INDEX SL MACRO DEFINITION
.INDEX SL MACRO
.INDEX MACROS - SL
.BREAK
#;	DEFINES A VALUE PARAMETER WHOSE DEFAULTS
.BREAK
#;	    ARE DEFINED AT THE BEGINNING OF THE PROGRAM
.BREAK
#;	    BY "DM" USING THE SAME ABBREVIATION
.BREAK
#;	PROCESSOR IS THE JUMP ADDRESS IN SWITCH PROCESSING
.BREAK
#;	    IT WILL BE CALLED WITH P1=SWITCH OFFSET IN TABLE
.BREAK
#;	    AND P2=POINTER TO 4-WORD BLOCK OF
.BREAK
#;	    INTERNAL OR EXTERNAL STUFF
.BREAK
#;	IF MAX=0 AND FS.LRG, THEN ANY VALUE CAN BE STORED
.BREAK
#;	    ELSE, 0.LE.VALUE.LE.MAX
.BREAK
#;
.BREAK
#;	0.LE.MAX,DEFAULT.LT.2**17 UNLESS FS.LRG
.BREAK
#;
.BREAK
#;	IF MAX=0 AND NOT FS.LRG, THEN
.BREAK
#;	PROCESSOR IS AN IMMEDIATE ACTION
.BREAK
#;	    WHICH WILL ALWAYS BE CALLED
.BREAK
#;	    ELSE, PROCESSOR WILL BE CALLED ONLY IF ":"
.BREAK
#;
.BREAK
#; SS  NAME,STORAGE,VALUE,FLAGS
.INDEX SS MACRO DEFINITION
.INDEX SS MACRO
.INDEX MACROS - SS
.BREAK
#;	DEFINES A STAND-ALONE PARAMETER
.BREAK
#;
.BREAK
#;	IN ALL CASES, STORAGE IS A BYTE POINTER.
.BREAK
#;	    IF A FULL WORD, ONLY THE ADDRESS IS NEEDED
.BREAK
#;	    IF A MULTIPLE WORD, THE BYTE SIZE IS 65-_#WORDS 
.BREAK
#;	    (UP TO 28)
.BREAK
#;	    IF A FILE SPECIFICATION, THE LENGTH IS HELD 
.BREAK
#;	    IN MX.ABBREVIATION
.BREAK
#;	    IF POINTER IS 7777??,,?????? THEN RH(POINTER) 
.BREAK
#;	    IS DISPATCH ADDRESS OF PROCESSOR WHICH TAKES
.BREAK
#;	    KEYWORD SWITCH VALUES
.BREAK
#;
.BREAK
#; SN  NAME,STORAGE,FLAGS
.INDEX SN MACRO DEFINITION
.INDEX SN MACRO
.INDEX MACROS - SN
.BREAK
#;	DEFINES A STAND-ALONE PARAMETER WHICH TAKES VALUE
.BREAK
#;	    1 IF /NAME, AND VALUE 0 IF /NONAME
.BREAK
#
.BREAK
#;FLAGS WHICH CAN BE DEFINED IN SWITCH TABLE
.BREAK
.INDEX FS.??? FLAGS
#>FS.NFS==1B0	;THIS SWITCH IS NEVER PART OF A 
.BREAK
#		;FILE SPECIFICATION
.BREAK
#		; THIS SHOULD BE SET ON GLOBAL SWITCHES
.BREAK
#		; ** VERY IMPORTANT TO GET RIGHT **
.BREAK
#>FS.LRG==1B1	;THE MAX AND DEFAULT VALUES ARE 0 OR .GT. 2**17
.BREAK
#>FS.NUE==1B2	;NO USER EXIT ON THIS SWITCH
.BREAK
#>FS.VRQ==1B3	;VALUE REQUIRED
.BREAK
#>FS.OBV==1B4	;OR BIT VALUES TO RIGHT HALF
.BREAK
#>FS.NOS==1B5	;SWITCH TAKES "NO" PREFIX 
.BREAK
#		;(INTERNAL FOR SN MACRO ONLY)
.BREAK
#>FS.NCM==1B6	;SWITCH DOES NOT CONSTITUTE A COMMAND  [102]
.BREAK
#		; (FOR /RUN, /OPTION, /EXIT)
.BREAK
.BREAK
# 
.BREAK
.page
.BREAK
#;WORDS IN FILE SPEC AREA
.BREAK
.INDEX .FX??? OFFSETS
#.FXDEV==0	;DEVICE   (NON-ZERO IF ANY PART OF SPEC)
.BREAK
#.FXNAM==1	;NAME   (NON-ZERO IF NAME PRESENT)
.BREAK
#.FXNMM==2	;NAME MASK
.BREAK
#.FXEXT==3	;EXTENSION,,EXTENSION MASK  (NON-ZERO DOT PRESENT)
.BREAK
#.FXMOD==4	;MODIFIER WORD
.BREAK
#.FXMOM==5	;MODIFIER MASK
.BREAK
#.FXDIR==6	;DIRECTORY WORD   (EACH HALF=0 IF DEFAULT; 
.BREAK
#		;SFD:0 IF END)
.BREAK
#.FXDIM==7	;DIRECTORY MASK
.BREAK
#.FXBFR==22	;/BEFORE
.BREAK
#.FXSNC==23	;/SINCE
.BREAK
#.FXABF==24	;/ABEFORE
.BREAK
#.FXASN==25	;/ASINCE
.BREAK
#.FXFLI==26	;FILE MIN SIZE (WORDS)
.BREAK
#.FXFLM==27	;FILE MAX SIZE (WORDS)
.BREAK
#.FXEST==30	;/ESTIMATE
.BREAK
#.FXVER==31	;/VERSION
.BREAK
#
.BREAK
#;LENGTHS OF FILE SPEC AREA
.BREAK
#.FXLEN==32	;LENGTH OF ONE SPECIFICATION
.BREAK
#.FXLND==6	;LENGTH OF DIRECTORY (UFD+SFD'S)
.BREAK
#
.BREAK
#;BYTES IN SCAN MOD WORD
.BREAK
.INDEX FS.??? SYMBOLS
#FX.NDV==1B0	;NULL DEVICE
.BREAK
#FX.NUL==1B1	;NULL EXTENSION
.BREAK
#FX.DIR==1B2	;DIRECTORY SPECIFIED   (MOD=0 IF [-])
.BREAK
#FX.PHY==1B3	;/PHYSICAL
.BREAK
#FX.NOM==1B4	;/OKNONE
.BREAK
#FX.DFX==1B5	;DIRECTORY DOES NOT NEED FIX-UP BY WILD
.BREAK
#FX.TRM==7B8	;CODE FOR SPEC'S TERMINATION
.BREAK
#	.FXTRA==1	;_& (AND)
.BREAK
#	.FXTRO==2	;! (OR)
.BREAK
#	.FXTRN==3	;- (NOT)
.BREAK
#	.FXTRC==4	;+ (CONCATENATE)
.BREAK
#FX.STR==1B9	;/STRS
.BREAK
#FX.PRT==1B10	;/OKPROT
.BREAK
#FX.SUP==1B11	;/ERSUPERSEDE
.BREAK
#
.BREAK
#FX.DEN==7B23	;/DENSITY   	[105]
.BREAK
#FX.PAR==1B24	;/PARITY
.BREAK
#FX.PRO==777B35	;/PROTECTION
.BREAK
.BREAK
# 
.BREAK
.page
.BREAK
#;SPECIAL CHARACTERS FOR SCAN
.BREAK
.INDEX .CH??? SYMBOLS
#.CHALX==0	;ALTMODE
.BREAK
#.CHEOL==-1	;END OF LINE
.BREAK
#.CHEOF==-2	;END OF FILE
.BREAK
#
.BREAK
#;GUIDE WORDS (TURNED INTO PSEUDO CHARACTERS)
.BREAK
#
.BREAK
.INDEX GUIDE WORDS
#.CHAND==4000	;'AND'					[101]
.BREAK
#.CHOR==04001	;'OR'					[101]
.BREAK
#.CHNOT==4002	;'NOT'					[101]
.BREAK
#.CHTO==04003	;'TO'					[103]
.BREAK
#.CHFRM==4004	;'FROM'					[103]
.BREAK
#.CHINP==4005	;'INPUT'				[103]
.BREAK
#.CHOUT==4006	;'OUTPUT'				[103]
.BREAK
#.CHSRC==4007	;'SOURCE'				[103]
.BREAK
#.CHLST==4010	;'LIST'					[103]
.BREAK
#.CHOBJ==4011	;'OBJECT'				[103]
.BREAK
#
.BREAK
#
.BREAK
#;FLAGS FOR .ISCAN CALL
.BREAK
#
.BREAK
.INDEX FS.ICL
.INDEX .ISCAN
.INDEX ISCAN FLAGS
.INDEX .ISCAN FLAGS
#FS.ICL==1B17	;IGNORE SPECIAL COMMAND-LINE HANDLING
.BREAK
#
.BREAK
#;FLAGS FOR .TSCAN CALL
.BREAK
#
.BREAK
.INDEX .TSCAN
.INDEX FS.MOT
.INDEX FS.MIO
.INDEX TSCAN FLAGS
.INDEX .TSCAN FLAGS
#FS.MOT==1B18	;MULTIPLE OUTPUT SPECS POSSIBLE
.BREAK
#FS.MIO==1B19	;MIXED INPUT AND OUTPUT SPECS
.BREAK
#
.BREAK
#;FLAGS FOR .TDIRB CALL
.BREAK
#
.BREAK
.INDEX TS.DRW
.INDEX TS.DRP
.INDEX TS.DRB
.INDEX .TDIRB FLAGS
.INDEX .TDIRB
#TS.DRW==0	;SINGLE WORD
.BREAK
#TS.DRP==1	;PATH POINTER
.BREAK
#TS.DRB==2	;BIWORD (IE, SCAN SPEC FORMAT)
.BREAK
#
.BREAK
#;VALUES FROM .VERBO
.INDEX .VERBO
.INDEX .VERBO FLAGS
.INDEX JWW.CN
.INDEX JWW.FL
.INDEX JWW.PR
.BREAK
#
.BREAK
#JWW.CN==1B33	;/VERBOS:CONTINUATION
.BREAK
#JWW.FL==1B34	;/VERBOS:FIRST
.BREAK
#JWW.PR==1B35	;/VERBOS:PREFIX
.BREAK
.appendix _$SCNDC:  COMMAND SCANNER DECLARATIONS
.index _$scndc
.SKI 5
 _$SCNDC is a part of SCAN.MAC, which generates _$SCNDC.UNV
whenever SCAN is assembled.  It contains the definitions of
some SCAN/WILD related symbols, and the accumulators, for use
by programs which must interface with SCAN _& WILD. It is accessed
by the
.skip 1
.indent 10;SEARCH _$SCNDC
.skip 1
statement at the beginning of the program using SCAN or WILD.
.skip 5
.BREAK
#
.BREAK
#
.BREAK
#	UNIVERSAL  _$SCNDC -- DECLARATIONS FOR COMMAND SCANNER
.BREAK
#	SEARCH	C,SCNMAC	;SEARCH PARAMETERS FOR THIS FILE
.BREAK
#
.BREAK
#;AC NAMES
.INDEX REGISTER MNEMONICS
.INDEX ACCUMULATOR NAMES
.BREAK
#
.BREAK
#T1=1		;TEMPORARIES
.BREAK
#T2=2
.BREAK
#T3=3
.BREAK
#T4=4
.BREAK
#
.BREAK
#P1=5		;PRESERVED ACS FOR CALLING ROUTINES
.BREAK
#P2=6
.BREAK
#P3=7
.BREAK
#P4=10
.BREAK
#
.BREAK
#P=17		;PUSH-DOWN POINTER
.BREAK
#
.BREAK
#
.BREAK
#DM MSG,77777,0,7	;MESSAGE
.BREAK
#DM PRO,777,0,277	;PROTECTION
.BREAK
#DM RNC,777777,0,0	;RUN CORE
.BREAK
#DM RUN,7,-1,1		;RUN OFFSET
.BREAK
#
.BREAK
#VRBADX==10		;/MESSAGE:ADDRESS
.BREAK
#
.BREAK
#PRGEND
.BREAK
.appendix EXAMPLES:  SCAN'S INTERNAL SWITCH TABLES
.SKIP 5
 It was mentioned at various points in the text that SCAN
has certain switches built into it.  As might be expected,
SCAN uses itself to process htese switches.  Therefore, it is
interesting and useful to see just how SCAN defines its
own switches, using the DOSCAN, SWTCHS, DM and KEYS macros.
.skip 5
.BREAK
#
.BREAK
#
.BREAK
#
.BREAK
#
.BREAK
#;HERE WE DEFINE STANDARD SWITCHES PROCESSED IN SCAN
.BREAK
#
.BREAK
#	DEFINE	SWTCHS,<
.BREAK
#SP ABEFORE,F.ABF,.SWDTP,,FS.VRQ
.BREAK
#SP ASINCE,F.ASN,.SWDTP,,FS.VRQ
.BREAK
#SP BEFORE,F.BFR,.SWDTP,,FS.VRQ
.BREAK
#SL DENSITY,<POINTR (F.MOD,FX.DEN)>,DENS,DENSIN
.BREAK
#SS ERNONE,<POINTR (F.MOD,FX.NOM)>,0
.BREAK
#SS ERPROTECTION,<POINTR (F.MOD,FX.PRT)>,0
.BREAK
#SS ERSUPERSEDE,<POINTR (F.MOD,FX.SUP)>,1
.BREAK
#SP ESTIMATE,F.EST,.BLOKW,,FS.VRQ
.BREAK
#SP EXIT,N.DEV,SWEXIT,,FS.NFS!FS.NCM
.BREAK
#SL *HELP,<-1,,.SWHLP>,HELP,HELPTEXT,FS.NFS!FS.NCM
.BREAK
#SP LENGTH,F.FLM,SWLEN,,FS.VRQ
.BREAK
#SL MESSAGE,<*F,.FLVRB_#_#>,VRB,PD.MSG,FS.OBV!FS.NFS!FS.NCM
.BREAK
.BREAK
#SS NOOPTION,OPTION,0,FS.NFS!FS.NCM
.BREAK
.BREAK
# 
.BREAK
.BREAK
#SS OKNONE,<POINTR (F.MOD,FX.NOM)>,1
.BREAK
#SS OKPROTECTION,<POINTR (F.MOD,FX.PRT)>,1
.BREAK
#SS OKSUPERSEDE,<POINTR (F.MOD,FX.SUP)>,0
.BREAK
.BREAK
#SP OPTION,OPTION,.SWSIX,OPT,FS.NFS!FS.NCM
.BREAK
.BREAK
#SL PARITY,<POINTR (F.MOD,FX.PAR)>,PAR,PARODD
.BREAK
#SN PHYSICAL,<POINTR (F.MOD,FX.PHY)>
.BREAK
#SP PROTECTION,<POINTR (F.MOD,FX.PRO)>,.SWOCT,PRO
.BREAK
.BREAK
#SP RUN,N.ZER,.SWFIL,RNL,FS.NFS!FS.NCM!FS.VRQ
.BREAK
#SP RUNCORE,N.CORE,.SWCOR,RNC,FS.LRG!FS.NFS!FS.NCM
.BREAK
#SP RUNOFFSET,N.OFFS,.SWOCT,RUN,FS.NFS!FS.NCM
.BREAK
.BREAK
#SP SINCE,F.SNC,.SWDTP,,FS.VRQ
.BREAK
#SN STRS,<POINTR (F.MOD,FX.STR)>
.BREAK
#SP TMPFILE,,SWTMP,,FS.VRQ!FS.NFS!FS.NCM
.BREAK
#SP VERSION,F.VER,.VERSW,,FS.VRQ
.BREAK
#>
.BREAK
#
.BREAK
.PAGE
#;NOW BUILD THE TABLES FROM THE SWTCHS MACRO
.BREAK
#	MX.OPT==1
.BREAK
#	PD.OPT==0
.BREAK
#	MX.RNL==N.EZER-N.ZER+1
.BREAK
#	PD.RNL==0
.BREAK
#
.BREAK
#
.BREAK
#	DOSCAN	(STSWT)
.INDEX DOSCAN MACRO
.INDEX MACROS - DOSCAN
.BREAK
#
.BREAK
#
.BREAK
#;HERE WE BUILD THE KEYS
.BREAK
#
.BREAK
#KEYS (DENS,<200,556,800,1600,6250,%%,_$_$,INSTALLATION>)
.BREAK
#KEYS (HELP,<SWITCHES,TEXT>)
.BREAK
#KEYS (PAR,<EVEN,ODD>)
.BREAK
#				;    --DUMMIES--		[321]
.BREAK
#KEYS (VRB,<PREFIX,FIRST,CONTINUATION,_$_$,_$%,%_$,%%,ADDRESS>)
.BREAK
# 
.BREAK
.page
.BREAK
.appendix EXAMPLES:  ALKFIL
.SKIP 5
 ALKFIL is a non-DEC program written to perform the  tasks
of file space allocation.  It uses SCAN to process the command
lines, and is a useful example of the various options available
to the SCAN _& WILD user.
.skip 5
.BREAK
#
.BREAK
.BREAK
#DEFINE	SWTCHS<
.BREAK
#SP	SIZE,FILSIZ,.DECNW_#_#,FIL,FS.VRQ!FS.NCM		;[_#46]
.BREAK
#SP	MINDRIVES,MINDRV,.DECNW_#_#,MND,FS.VRQ!FS.NFS	;[_#51]
.BREAK
#SP	MAXDRIVES,MAXDRV,.DECNW_#_#,MND,FS.VRQ!FS.NFS	;[_#51]
.BREAK
#SP	PARTITIONS,PARTNS,GETPRT_#_#,PRT,FS.VRQ!FS.NFS
.BREAK
#SP	REPEAT,RPTFCT,.DECNW_#_#,RPT,FS.VRQ!FS.NFS	;[_#33]
.BREAK
#SL	SPLIT,SPLIND,SPLT,,FS.VRQ!FS.NFS
.BREAK
#SL	ALLOCATE,ALCIND,ALOC,,FS.VRQ!FS.NFS
.BREAK
#SL	ADDRESSING,ADRIND,ADRS,,FS.VRQ!FS.NFS
.BREAK
#SP	BUFSIZ,BUFSIZ,.DECNW_#_#,BUFS,FS.VRQ!FS.NFS
.BREAK
#SP	UNIT,UNINAM,GETUNI_#_#,,FS.VRQ!FS.NFS		;[_#25]
.BREAK
#SP	BLOCK,BLKNUM,GETBLK_#_#,,FS.VRQ!FS.NFS		;[_#23]
.BREAK
#SP	LBN,LBNNUM,GETLBN_#_#,,FS.VRQ!FS.NFS		;[_#31]
.BREAK
.BREAK
#SP	STATUS,STSOBJ,.SIXSW_#_#,,FS.NFS			;[_#25]
.BREAK
#SS	STRSTS,<POINTR(F,F.STRS)>,1
.BREAK
#SS	CREATE,<POINTR(F,F.CREA)>,1
.BREAK
#SS	PREALLOC,<POINTR(F,F.PRAL)>,1
.BREAK
#SS	COPY,<POINTR(F,F.COPY)>,1
.BREAK
.BREAK
#SS	NOLOG,<POINTR(F,F.NLOG)>,1			;[_#46]
.BREAK
.BREAK
#SP	SPOOL,SPOOL,.SIXSW_#_#,,FS.VRQ!FS.NFS		;[_#57]
.BREAK
#SS	DEBUG,<POINTR(F,F.DEBG)>,1			;[_#60]
.BREAK
#>
.BREAK
#
.BREAK
#
.page
#;EXPAND SWITCH TABLES FOR SCAN:
.BREAK
#DOSCAN(SWIT)
.INDEX MACROS - DOSCAN
.INDEX DOSCAN MACRO
.BREAK
#
.BREAK
#
.BREAK
#;DEFINE DEFAULTS AND KEY-LISTS
.BREAK
#
.BREAK
#;	NAME,MAX,ABSENT-DEFAULT,PRESENT-DEFAULT
.BREAK
#DM	(MND,_^D31,1,1)				;[_#51]
.BREAK
#DM	(MXD,_^D32,32,32)			;[_#51]
.BREAK
#DM	(PRT,_^D65,_^D30,1)			;[_#65]  
#				;0 IMPLIES MINIMUM NEEDED
.BREAK
#INTERNAL	MX.PRT,AD.PRT			;[_#43]  FOR USE
.BREAK
						;[_#43]  BY OTHER
.BREAK
						;[_#43]  MODULES
.BREAK
#DM	(RPT,1,1,1)				;[_#32]
.BREAK
#DM	(BUF,_^D100,_^D25,_^D5)			;[_#52]
.BREAK
#DM	(FIL,377777,_^D1000,_^D1000)		;[_#40]
.BREAK
#
.BREAK
# 
.BREAK
.BREAK
#;******** IMPORTANT *********
.BREAK
#;IF THE ORDER OF ARGUMENTS TO THE KEYS MACRO
.BREAK
#;IS CHANGED, THEN THE CORRESPONDING _$_$XXX
.BREAK
#;TABLE MUST ALSO BE CHANGED.
.BREAK
#
.BREAK
#KEYS	(SPLT,<BEST,LINEAR,PROMPT>)	;[_#61]
.BREAK
#KEYS	(ALOC,<SPACE,PHYSICAL,LOGICAL,PROMPT>)  ;[_#60]
.BREAK
#KEYS	(ADRS,<FIRST,PROMPT>)		;[_#22]
.BREAK


.appendix CUSPS _& THEIR SCANNERS
.skip 5
 Not all DEC programs use SCAN _& WILD.  Most of the more recent
(from about 1976 on) tend to use it, and some of the older ones
use it.  Many of the remaining programs, especially the very old
CUSPS (REACT, SOUP, etc.) each have their own code to process their
own (usually different) styles of commands.  The list that follows
indicates which DEC (and some non-DEC) programs use SCAN, and
which use their own scanners.  It should proves useful as a
source of further information on using scan.  In particular, the
module LNKSCN of LINK-10 is an excellant reference
to using the switch-defining macros.

.nojust
.nofill
.noautopar
.skip 5
CUSP		SCANNER		COMMENTS
----------	------------	-----------------------
.skip 2
ALGOL		own
BACKUP		SCAN		.VSCAN
.INDEX VSCAN
.INDEX .VSCAN
BASIC		own
BATCON (MPB)	own
BATCON (GALAXY)	SCAN
BLISS-10	own		Compiler fake's it (no SFDs)
BOOT11		own
CHANGE		own
COBOL		own
COMPIL		own
CREDIR		SCAN		Uses .PSCAN
.INDEX .PSCAN
.INDEX PSCAN
.PAGE
CUSP		SCANNER		COMMENTS
----------	------------	-----------------------
.skip 2
CREF		own
DAEMON		old SCAN	Has SCAN V2 built into it
DIRECT		SCAN
FILCOM		own
FILEX		own
FORTRAN-10	SCAN
GALAXY		SCAN		All components
HELP		SCAN
INITIA		own		even simulates .OSCAN
.INDEX .OSCAN
.INDEX OSCAN
ISAM		own
JQ		SCAN		(non-DEC)  uses .TSCAN
.INDEX .TSCAN
.INDEX TSCAN
KJOB (MPB)	own
LIBARY		own
LINED		own
LINK-10		SCAN		Excellant example (LNKSCN)
LOGIN		SCAN
LOGOUT (MPB)	own
LOGOUT (GALAXY)	SCAN
LPTSPL (MPB)	own		Same for other spoolers
LPTSPL (GALAXY)	SCAN		-dittoe-
MACRO		own
MAIL		own		(non-DEC) good job of faking it
MAKLIB		SCAN
OMOUNT		own
OPSER		own
PIP		own
QUEUE (MPB)	SCAN		.TSCAN
.INDEX TSCAN
.INDEX .TSCAN
QUEUE (GALAXY)	SCAN		.TSCAN
.INDEX TSCAN
.INDEX .TSCAN
REACT		own
RERUN		own
RUNOFF		SCAN		.TSCAN
.INDEX .TSCAN
.INDEX TSCAN
SETSRC		own
SORT-10		SCAN
SOS		own
SOUP		own
SYSTAT		own
TECO		own
UMOUNT		own
.fill
.just
.autopar
.CHAPTER ##INDEX


.LM 1
.SPACING 1
.DO INDEX