	.ENABLE SUBSTITUTION
;+
;		'<FILSPC>'
;
;	Run the crashdump analyzer.
;-

.; The following are used to customize to a particular
.; installation. 

.;	S$MEDA must be set to the device name for a
.;	representative device on which your save media may be
.;	mounted. 

	.SETS S$MEDA "LB0:"	! Device type for save media.

.; The supported systems must be defined via
.;	.SETS sysnam "cdanal;memsiz;crdev;blk;stbnam;hlptxt"
.;   Where:
.;	sysnam	is the name of the system to which the 
.;			information pertains;
.;	cdanal	is the name of the crash dump analyzer task
.;			file - the defaults are:
.;				device ---- LB:
.;				directory - <LIBUIC>
.;				name ------ CDA
.;				type ------ .TSK
.;	memsiz	is the memory size for the system;
.;	crdev	is a list of legal crash devices (separated by
.;			commas);
.;	blk	is the block on which the crash dump starts;
.;	stbnam	is the STB file name - the defaults are:
.;				device ---- LB:
.;				directory - <SYSUIC>
.;				name ------ RSX11M
.;				type ------ .STB
.;	hlptxt	is identifying text for the system.
.;
.;	If your system name is not a defined symbol, the
.;		crashdump will not be run. 
.;

.SETS HOST "CDAFSL;256;DR;2;;RSX-11M+ system."
.SETS FRONT "CDA41;124;DX,DY;1;[1,64];RSX-11S system."
.SETS OTHER "CDAFSL;512;DR;2;OTHER;Another M+ system."


.;
.;	Other initialization.
.;

	.ENABLE ESCAPE
	.SETS S$AYE "A"
	.SETS S$ZEE "Z"
	.SETS S$OUIC <UIC>
	.SETS S$MCR "MCR "	! Explicitly pass MCR commands.
	.IF <CLI> = "MCR" .SETS S$MCR ""	! In MCR already
	.SETS S$CHRS "01234567ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	.TESTDEVICE TI:
	.PARSE <EXSTRI> ":" S$TI S$JUNK
	.SETS S$CDTK "CDA"+S$TI[1:1]
	.SETS S$JUNK S$TI[3:*]
	.SETN N$JUNK 'S$JUNK'/10+1
	.IF N$JUNK > 0 .SETS S$CDTK S$CDTK+S$CHRS[N$JUNK:N$JUNK]
	.SETN N$JUNK 'S$JUNK'&7+1
	.SETS S$CDTK S$CDTK+S$CHRS[N$JUNK:N$JUNK]
	.SETS S$NOGO ",COMMAN,P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,"

	.IFF <PRIVIL>		.GOTO ERRPRV


.;
.;	Get the system being dumped.
.;

.SYSASK:
	;
	.DISABLE LOWERCASE
	.ASKS [0:6:<NETNOD>] S$SYS What system is crashdump for
	.ENABLE LOWERCASE
	.IFT <ESCAPE>	.GOTO SYSHLP
	.IFF <ALPHAN>	.GOTO SYSERR
	.TEST S$NOGO ",'S$SYS',"
	.IF <STRLEN> > 0	.GOTO SYSERR
	.IFDF 'S$SYS'	.GOTO SYSOK
.SYSERR:;
	; Error - System name "'S$SYS'" is invalid, or not
	;		supported by this command file. 
.SYSHLP:;
	; Valid system names are:
	.SETS <NXTSYM> ""

.; Now, loop through the Symbol Table:

.SYSHLL:

	.; Get the next Symbol name; if none, we are done:

	.SETS S$SYS <NXTSYM>
	.IF S$SYS = ""	.GOTO SYSASK

	.; If it is not alphanumeric, we do not want it:

	.TEST S$SYS
	.IFF <ALPHAN>	.GOTO SYSHLL

	.; If it is not a String Symbol, we do not want it:

	.TEST 'S$SYS'
	.IF <SYMTYP> <> 4	.GOTO SYSHLL

	.; If it is COMMAN or P0-P9, we do not want it:

	.TEST S$NOGO ",'S$SYS',"
	.IF <STRLEN> > 0	.GOTO SYSHLL

	.; It it a legal system name; pick it apart and display
	.; the identifying text;

	.PARSE 'S$SYS' ";" S$CDA S$MEM S$CDL S$CBK S$STB S$HELP
	;         'S$SYS%L6' - 'S$HELP'

	.; Go get the next Symbol:

	.GOTO SYSHLL

.SYSOK:	.; Have a valid system name.
	.PARSE 'S$SYS' ";" S$CDA S$MEM S$CDL S$CBK S$STB S$HELP
	@LB:[1,2]INDSYS/LB:INDPRF/-TR 'S$CDA'
	.PARSE <EXSTRI> "\" S$NOD S$DEV S$DIR S$CDA S$TYP S$JUNK
	.IF S$DEV = ""	.SETS S$DEV "LB"
	.IF S$DIR = ""	.SETS S$DIR <LIBUIC>
	.IF S$CDA = ""	.SETS S$CDA "CDA"
	.IF S$TYP = ""	.SETS S$TYP "TSK"
	.SETS S$CDA S$DEV+":"+S$DIR+S$CDA+"."+S$TYP
	@LB:[1,2]INDSYS/LB:INDPRF/-TR 'S$STB'
	.PARSE <EXSTRI> "\" S$NOD S$DEV S$DIR S$STB S$TYP S$JUNK
	.IF S$DEV = ""	.SETS S$DEV "LB"
	.IF S$DIR = ""	.SETS S$DIR <SYSUIC>
	.IF S$STB = ""	.SETS S$STB "RSX11M
	.IF S$TYP = ""	.SETS S$TYP "STB"
	.SETS S$STB S$DEV+":"+S$DIR+S$STB+"."+S$TYP
	.TESTFILE 'S$CDA'
	.IF <FILERR> <> 1	.GOTO ERRCDA
	.GOSUB DEFDEV 'S$CDL'
	.SETS S$CDVD COMMAN

.;
.;	Get the device for the crashdump binaries.
.;

.DEVASK:
	;
	.ASKS [0:5:S$CDVD] S$CDVC Where is the crash medium
	.GOSUB DEVCHK 'S$CDVC'\'S$CDVD'
	.IF COMMAN = ""	.GOTO DEVASK
	.SETS S$CDVC COMMAN
	.SETT L$DELE
	.SETS S$SAVE S$CDVC
	.ASK [<TRUE>] L$COPY Copy crash file to save medium
	.IFF L$COPY	.GOTO PROC
	.ASK [<TRUE>] L$DELE Delete crash file after copying


.;
.;	Process the system spec to find out what we need.
.;

.PROC:	.;
	.TESTFILE 'S$STB'
	.IF <FILERR> <> 1	.GOTO ERRSTB


.;
.;	See if all the files are there.
.;

.;
.;	Do the analysis.
.;

	;
	'S$MCR'ASN LB:=SY:
	'S$MCR'SET /UIC=[1,1]
	.TEST S$STB "LB:"
	.IF <STRLEN> = 1	.SETS S$STB S$STB[4:*]
	.TEST S$STB ".STB"
	.IF <STRLEN> > 0	.SETS S$STB S$STB[1:<STRLEN>-1]
	.TESTDEVICE 'S$CDVC'
	.PARSE <EXSTRI> "," S$CDVC S$JUNK
	.SETF L$PUB
	.TEST <EXSTRI> ",PUB,"
	.IF <STRLEN> <> 0	.SETT L$PUB
	.SETF L$MTD
	.TEST <EXSTRI> ",MTD,"
	.IF <STRLEN> <> 0	.SETT L$MTD
	.IFF L$MTD	'S$MCR'MOU 'S$CDVC'/FOR
	'S$MCR'INS 'S$CDA'/TASK='S$CDTK'
	.SETS S$JUNK "'S$SYS','S$SYS'/MEMSIZ:'S$MEM'."
	.SETS S$JUNK S$JUNK+"='S$STB'/STB,'S$CDVC'"
	.SETS S$JUNK S$JUNK+"/BL:'S$CBK'./ATL/PAR/POOL"
	'S$MCR'CDA 'S$JUNK'
	'S$MCR'REM 'S$CDTK'
	.IFT L$PUB	'S$MCR'DMO 'S$CDVC'/DEV
	.IFF L$PUB	'S$MCR'DMO 'S$CDVC'

.;
.;	Copy binary file to save medium.
.;

	.IFF L$COPY	.GOTO COPYOK
	.TESTDEVICE 'S$MEDA'
	.SETS S$MEDA <EXSTRI>[1:2]
	;
	.IF S$MEDA = S$CDVC[1:2]	.GOTO SAVPRC
	.GOSUB DEFDEV 'S$MEDA'
	.SETS S$SVDF COMMAN
.SAVASK:
	.ASKS [0:5:S$SVDF] S$SAVE Where is save medium mounted
	.GOSUB DEVCHK 'S$SAVE'\'S$SVDF'
	.IF COMMAN = ""	.GOTO SAVASK
	.SETS S$SAVE COMMAN
.SAVPRC:.;
	.TESTDEVICE 'S$SAVE'
	.PARSE <EXSTRI> "," S$SAVE S$JUNK
	.SETF L$PUB
	.TEST <EXSTRI> ",PUB,"
	.IF <STRLEN> <> 0	.SETT L$PUB
	.SETF L$MTD
	.TEST <EXSTRI> ",MTD,"
	.IF <STRLEN> <> 0	.SETT L$MTD
.COPYDO:.ASK [<FALSE>] L$JUNK Is save medium mounted on 'S$SAVE'
	.IFF L$JUNK	; I will pause while you mount it.
	.IFF L$JUNK	.PAUSE
	.IFF L$JUNK	.GOTO COPYDO
	;
	'S$MCR'MOU 'S$SAVE'CRASH
	.IF <EXSTAT> <> <SUCCES>	.GOTO COPYOK
	'S$MCR'PIP 'S$SAVE'/UF='S$SYS'.CDA
	.IF <EXSTAT> = <SUCCES> .IFT L$DELE	'S$MCR'PIP 'S$SYS'.CDAFSL;*/DE/NM
	.IFT L$PUB	'S$MCR'DMO 'S$SAVE'/DEV
	.IFF L$PUB	'S$MCR'DMO 'S$SAVE'
.COPYOK:.; Copy done.

	.IF <UIC> <> S$OUIC	'S$MCR'SET /UIC='S$OUIC'
	'S$MCR'ASN =SY:
	.EXIT <SUCCES>

.DEFDEV:
.;
.;	Determine the default device from a given list.
.;
	.BEGIN
	.SETS SD$LST COMMAN
.DDFDVL:
	.SETN OD$UNT 0
	.PARSE SD$LST "," SD$DEV SD$LST
	.IFLOA 'SD$DEV':	.GOTO DDFLP
	.IF S$JUNK <> ""	.GOTO DDFDVL
	.SETS COMMAN ""
	.GOTO DDFXIT

.DDFLP:
	.TESTDEVICE 'SD$DEV''OD$UNT':
	.INC OD$UNT				! Next dev.
	.PARSE <EXSTRI> "," SD$DVC S$JUNK	! Get default.
	.TEST <EXSTRI> "NSD,"			! More units?
	.IF <STRLEN> <> 0	.GOTO DDFDVL	! If not, err.
	.IF SD$DEV <> SD$DVC[1:2] .GOTO DDFLP	! If asn, next.
	.TEST <EXSTRI> ",ALO,"			! Allocated?
	.IF <STRLEN> <> 0	.GOTO DDFLP	! If so, next.
	.TEST <EXSTRI> ",OFL,"			! Offline?
	.IF <STRLEN> <> 0	.GOTO DDFLP	! If so, next.
	.TEST <EXSTRI> ",MTD,"			! Mounted?
	.IF <STRLEN> <> 0	.TEST <EXSTRI> ",NFO,"
	.IF <STRLEN> <> 0	.GOTO DDFLP	! If so, next.
	.SETS COMMAN SD$DVC
.DDFXIT:.END
	.RETURN

.;	DEVCHK - Make sure a device is OK to use.

.DEVCHK:
	.BEGIN
	.PARSE COMMAN "\" COMMAN SD$DEF
	.PARSE COMMAN ":" COMMAN S$JUNK
	.IFT <ESCAPE>	.GOTO DEVHLP
	.SETS SD$ERR "Device name 'COMMAN': has invalid format"
	.IF S$AYE > COMMAN[1:1]	.GOTO DEVERR
	.IF S$ZEE < COMMAN[1:1]	.GOTO DEVERR
	.IF S$AYE > COMMAN[2:2]	.GOTO DEVERR
	.IF S$ZEE < COMMAN[2:2]	.GOTO DEVERR
	.SETS SD$UNT "0"+COMMAN[3:*]
	.TEST SD$UNT
	.IFF <OCTAL>	.GOTO DEVERR
	.SETN OD$UNT 'SD$UNT'
	.IF OD$UNT > 377	.GOTO DEVERR
	.TESTDEVICE 'COMMAN':
	.SETS S$ERR "Device 'COMMAN': is not in your system"
	.TEST <EXSTRI> "NSD,"			! Non-existent?
	.IF <STRLEN> <> 0	.GOTO DEVERR	! If so, err.
	.PARSE <EXSTRI> "," COMMAN SD$UNT
	.SETS SD$UNT SD$DEF[1:2]
	.SETS S$ERR "Device 'COMMAN' is not a 'SD$UNT': device"
	.IF SD$UNT <> COMMAN[1:2]	.GOTO DEVERR
	.SETS S$ERR "Device 'COMMAN': is allocated to another"
	.TEST <EXSTRI> ",ALO,"			! Allocated?
	.IF <STRLEN> <> 0	.GOTO DEVERR	! If so, error.
	.SETS S$ERR "Device 'COMMAN': is offline"
	.TEST <EXSTRI> ",OFL,"			! Offline?
	.IF <STRLEN> <> 0	.GOTO DEVERR	! If so, error.
	.SETS S$ERR "Device 'COMMAN': is mounted FILES-11"
	.TEST <EXSTRI> ",MTD,"			! Mounted?
	.IF <STRLEN> <> 0	.TEST <EXSTRI> ",NFO,"
	.IF <STRLEN> <> 0	.GOTO DEVERR	! If so, error.
	.GOTO DEVOK
.DEVERR:;
	; Error - 'S$ERR'.
.DEVHLP:.SETS SD$UNT SD$DEF[1:2]
	;
	; You should specify the name of a device on the
	; 'SD$UNT': driver, in the form "ddnn:", where 
	;         "dd" is the device name (alphabetic)
	;         "nn" is an optional unit number (octal, in the
	;              range 0 to 377), with 0 being the
	;	       default. 
	;         ":"  is an optional piece of punctuation.
	;
	; The named device must be on line, not allocated to
	; another user, and not mounted as a FILES-11 device. 
	;
	; Logical assignments are legal, but must resolve to a
	; unit on the 'SD$UNT': driver. 
	.SETS COMMAN ""
.DEVOK:	.END
	.RETURN

.ERRSTB:;
	; Error - Cannot find symbol table file 'S$STB' for
	;         system 'S$SYS'::. The crashdump analysis can
	;         not be run.
	.GOTO ERRXIT

.ERRCDA:;
	; Error - Cannot find the crashdump analyzer task image
	;         file 'S$CDA' The crashdump
	;         analysis for 'S$SYS':: cannot be run.
	.GOTO ERRXIT

.ERRPRV:;
	; Error - You must be on a privileged terminal to run
	;	  this command file. 
	.GOTO ERRXIT

.ERRDEV:.SETS S$DLST S$CDL+": driver is"
	.SETS S$DTXT "this driver"
	.TEST S$CDL ","
	.IF <STRLEN> = 0	.GOTO ERRDEP
	.SETS S$DTXT "one of these drivers"
	.SETS S$DLST ""
	.SETS S$DLS1 S$CDL
	.SETN N$LAST 0
.ERRDEL:
	.TEST S$DLST
	.SETN N$LAST <STRLEN>
	.PARSE S$DLS1 "," S$DRV1 S$DLS1
	.SETS S$DLST S$DLST+", "+S$DRV1+":"
	.IF S$DLS1 <> ""	.GOTO ERRDEL
	.SETS S$JUNK S$DLST
	.SETS S$DLST S$JUNK[1:N$LAST]+", and"
	.SETS S$DLST S$DLST+S$JUNK[N$LAST+1:*]+" drivers are"

.ERRDEP:;
	; Error - The 'S$DLST' not in this system''s
	;         configuration. You need 'S$DTXT' to read the
	;         crashdump for 'S$SYS'. The crashdump analysis
	;         cannot be run.
	.GOTO ERRXIT

.ERRDNA:;
	; Error - There is no 'S$CRDV': unit available for
	;	  reading the crashdump. I need a device that is
	;	  online, unmounted, and not allocated to
	;	  another user. The crashdump analysis cannot be
	;	  run. 
	.GOTO ERRXIT

.ERRXIT:.IF <UIC> <> S$OUIC	SET /UIC='S$OUIC'
	.EXIT <ERROR>
