)CLEAR
)WSID SF2VX0

.DL MIGRATE;I;R;TYP;FIL;FTYP;DEV;PPN;CSET
"	MIGRATE IS AN INTERACTIVE FUNCTION THAT HELPS THE USER BUILD
"	A BATCH CONTROL FILE TO RUN ON THE -20 TO EXECUTE THE MIGRATION
"	TOOLS ON APLSF WORKSPACES AND DATA FILES.  IT CREATES MIGNNN. CTL
"	WHICH INVOKES APLSF (TERMINAL.. TT) FOR EACH FILE THAT IS TO BE
"	PROCESSED.  IT HANDLES FILES IN THE FOLLOWING CLASSES:  WORKSPACES,
"	/AS, /IS, /DA AND /BS FILES.  {NB: USER MUST SPECIFY CHARACTER
"	SET IN WHICH TO READ /AS FILES.}
"
"	FILE SPECS ON INPUT MAY CONTAIN DE:, [PPN], . TYP OR ,TYP.  FILE
"	SPECS THAT ARE OUTPUTTED WILL CONTAIN ,TYP.
"
"	IT TAKES A WILDCARD FILE SPEC OF FILES TO HANDLE IN THE SPECIFIED
"	CLASS, AND ACCEPTS THE FILE SPEC OF A WORKSPACE THAT CONTAINS A
"	FILTER FUNCTION (CALLED FILTER) THAT WILL BE RUN OVER THE WS.  FOR
"	FILES, THE FILE FUNCTION IS NAMED, EG DAFILTER, AND IS RUN WITH THE
"	NAME OF THE FILE AS THE RIGHT ARGUMENT BEFORE THE FILE IS PROCESSED.
"	THE FILE FILTER WORKSPACE MAY CONTAIN REPLACEMENT FUNCTIONS FOR, EG,
"	DAREAD, SO EACH RECORD OF THE FILE MAY BE PROCESSED BY THE USER BEFORE
"	THE FILE IS DUMPED TO A TEXT FILE TO BE )INPUTED TO VAX APL.
 
"	FOR R _ .EP')LIB ', F
"	  .  F MAY HAVE , OR . BEFORE FILE TYPE => CHANGE . TO , AND USE
"	     .QD INPUT TO PROTECT AGAINST TTY MNEMONICS
"	  .  R WILL CONTAIN . => CHANGE . TO ,
"	  .  IF F == F OR F,APL OR F,TYP OR DSK:F..., R'S 1ST LINE WILL SAY
"	     DSK: => REMOVE 1ST LINE IF IT CONTAINS A :
"	  .  IF F == DEV:F..., R'S 1ST LINE CONTAINS 1ST FILE SPEC AND DEV:
"	     NOT IN R
"	  .  IF F HAS NO *, R WILL BE A VECTOR => RESHAPE TO MATRIX
"	  .  IF F HAS A *, R IS A MATRIX, []PW WIDE, WITH FILENAMES RIGHT
"	     JUSTIFIED TO COLUMN 6 AND . FILETYPE IN COLUMN 7 IF THE TYPE IS
"	     NOT APL => REMOVE ALL BLANKS FROM ROW OF R BEFORE PROCESSING.
"	     NB: IF THE FILE TYPE IS . APL, ,APL WILL NOT BE PRESENT IN R.
"	  .  R == 0 E .RO 0 IF AN ERROR OCCURS
"	  .  IF F == DEV:F... AND F DOES NOT EXIST, 0 = .ROR;  IF F == F...
"	     OR DSK:F... AND F DOES NOT EXIST, R == DSK: => AFTER REMOVE 1ST
"	     ROW (IF IT CONTAINS :), IF 0 = .RO,R, THEN F DOES NOT EXIST.
"	  .  ")LIB DEV:,TYP" WORKS !
"	  .  ")LIB F*" DOESN'T WORK IN APLSF !
"	  .  ")LIB F-X" => 22 INCORRECT PARAMETER
"	  .  )LIB MUST HAVE [PPN] FOLLOW FILESPEC;  DEV: GOES BEFORE FILESPEC
"	  .  .BXERROR IS NOT SET IF THERE IS AN ERROR IN .EP')CMD'
 .BXIO_1
 .BXAI_.EP')ECHO OFF'
 FTYP_5 4.RO',APL,AAS,AIS,ADA,ABI'
T0:I_0
"          FIND A NON-EXISTENT MIGNNN . CTL FILE NAME
Q0:.BXAI_.BXASS '1 MIG',(,'ZI3'$I),',CTL/AS'
 R_.EP'.IQ[3]1'
 .GO(0 1 &.=.ROR)/OK0
 .GO(1000>I_I+1)/Q0
 .BXBREAK 'MIG000,CTL THRU 999 IN USE'
 .GO T0
OK0:.BXAI_.BXCLS 1
 .BXAI_('! BUILDING ',(.BXASS 1),' ',.FM.BXTS).OQ[2]1
 .BXAI_(.BXASCII[65],'NOERROR').OQ[2]1
Q1:I_.RO.QQ_'WHAT TYPE OF FILE DO YOU WISH TO MIGRATE? '
 .GO (6>TYP_''.RO'WAIDB'.IO1^I_I.DA,.QD)/Q2
 .GO('Q'=1^I)/A4
 .GO(')'.NE1^I)/E1A
"          EXECUTE THE USER'S SYSTEM COMMAND
 .GO(0 .EP .ROR_.EP I)/E1B
 .BX_R
 .GO Q1
E1B:'.EP ''',I,''' REPORTED ERROR ',.FM.ROR
 .GOQ1
E1A:'VALID FILE TYPES ARE W (WORKSPACE), A (/AS), I (/IS), D (/DA), B (/BS)'
 'OR ANY SYSTEM COMMAND TO BE EXECUTED'
 'OR Q (TO QUIT)'
 .GOQ1
Q2:FIL_FTYP[TYP;]
 I_.RO.QQ_'WHAT FILE SPEC? [CR TO REVERT] '
"          REMOVE LEADING BLANKS
 R_(.OR\R.NE' ')/R_I.DA,.QD
"          REMOVE TRAILING BLANKS
 R_(.RV.OR\.RVR.NE' ')/R
"          IS THERE ANY INPUT ?  NO => REVERT
 .GO(0=.ROR)/Q1
"          FIND AND REMOVE THE DEVICE: IF PRESENT
 DEV_(I_.RV.OR\.RVR=':')/R
 R_(.NTI)/R
"          FIND AND REMOVE THE [PPN] IF PRESENT
 PPN_(I_(.RV.OR\.RVI)&.OR\I_R.EP'[]')/R
 R_(.NTI)/R
"          CHANGE ANY . LEFT TO ,
 .XQ('.'.EPR)/'R[<\.OMR=''.'']_'','''
"          REASSEMBLE FILE SPEC, ADDING FILE TYPE IF NECESSARY
 FIL_DEV,R,((.NT','.EPR)/FIL),PPN
 .BXAI_('! MIGRATING ',FIL,' TYPE ',FTYP[TYP;]).OQ[2]1
 .GO((2 = .RO.ROR) & 0 .EP .ROR_.EP')LIB ',FIL)/E2B
 .XQ(2>.RO.ROR)/'R_(1,.ROR).ROR'
 .XQ(':'.EPR[1;])/'R_1 0 .DAR'
 .GO (0=.RO,R)/E2C
 CSET _ 2 4 .RO ' '
"	THE GLOBAL CSET IS USED TO DESCRIBE THE CHARACTER SET THAT IS TO BE
"	USED TO READ /AS FILES.  IF THE USER SPECIFIES THAT THE FILE IS /BIT,
"	THEN APLSF MUST BE EXECUTED "TERMINAL.. TT/BIT" SO ASDRIVER CAN USE
"	.QD MODE + APL CHARACTER SET.  THE LEFT ARGUMENT TO ASDRIVER IS 1 IF
"	THE FILE IS /TTY AND 2 IF IT IS /BIT OR /KEY.  CSET IS BLANK FOR ALL
"	OTHER FILE TYPES.
 .GO (2 .NE TYP)/Q4
Q3:I_.RO.QQ_'WHAT CHARACTER SET? [TTY OR BIT OR KEY] '
 .GO (0=.ROFIL_I.DA,.QD)/Q3
 .GO (3 < I_''.RO'TBK' .IO 1^FIL)/E3A
 .XQ (I=2)/'CSET[1;]_''/BIT'''
 CSET[2;2]_1 0 .FM I .FL 2
 .BXAI_('! USING CHARACTER SET /',(3 3.RO'TTYBITKEY')[I;]).OQ[2]1
 .GO Q4
E3A:'VALID CHARACTER SETS FOR READING /AS FILES ARE T (TTY), B (BIT), K (KEY)'
 .GO Q3
"          FIL CONTAINS THE NAME OF THE "FILTER" WS IF ANY
Q4:I_.RO.QQ_'USER DEFINED FILTER? [CR IF NONE] '
 .GO(0=.ROFIL_I.DA,.QD)/L
 .BXAI_('! USING FILTER ',FIL).OQ[2]1
L:I_(I.NE' ')/I_,R[1;]
 .XQ('.'.EPI)/'I[(<\I=''.'')/.IO.ROI]_'','''
 TYP PERFORM DEV,I,((.NT','.EPI)/FTYP[TYP;]),PPN
 .GO(0<1^.ROR_1 0.DAR)/L
Q5:I_.RO.QQ_'DO YOU HAVE MORE FILES TO PROCESS? [Y OR N] '
 .GO('Y'=1^I.DA,.QD)/Q1
A4:.BX_('! ',(.BXASS 1),' COMPLETED').OQ[2]1
 .BXAI_.BXDAS 1
 .GO 0
E2B:.BX_('ERROR ',(.FM.ROR),' IN FILESPEC ',FIL).OQ[2]1
 .GOQ2
E2C:.BX_(FIL,' DOES NOT EXIST').OQ[2]1
 .GOQ2
.DL
 
.DL TYP PERFORM NAME;T
"	PERFORM DUMPS . CTL LINES THAT INVOKE SOME DRIVER TO MIGRATE A WS
"	OR A FILE.  THE LEFT ARGUMENT IS THE "FILE TYPE" BEING PROCESSED
"	(1 .. 5 == WAIDB);  THE RIGHT ARGUMENT IS THE FILE SPEC.  GLOBAL
"	FIL IS THE FILE SPEC OF THE "FILTER".  GLOBAL CSET IS A 2 BY 4
"	MATRIX OF BLANKS UNLESS WE ARE PROCESSING A /AS FILE;  THEN CSET
"	HAS ITS FIRST ROW OF "/ALT" FOR THE ALTERNATE CHARACTER SET ON
"	"TERMINAL.." AND ITS SECOND ROW IS A 1 IF TTY ELSE 2.
"
"	ERROR 0 23.RO0 IS WS LOCKED; .BXASCII[65] IS THE RELIABLE AT-SIGN.
 .GO(TYP.NE1)/F
 T_.EP')PCOPY ',NAME,' PERFORM'
 .GO (.NT0 23 &.= ,.ROT)/OK1
 'WORKSPACE ', NAME, ' IS LOCKED'
 T_.RO.QQ_'WHAT IS THE PASSWORD? [CR TO SKIP THIS WS] '
 T_T.DA,.QQ
 .GO (0.NE.ROT)/OK2
 .BX_('! SKIPPING LOCKED WORKSPACE ',NAME).OQ[2]1
 .GO 0
OK1:T_''
OK2:.BXAI_(.BXASCII[65],'APLSF').OQ[2]1
 .BXAI_('*TT').OQ[2]1
 .BXAI_('*)MAXCORE 352').OQ[2]1
 .BXAI_('*)LOAD ',NAME,(0.NE.ROT)/'-',T).OQ[2]1
 .GO(0=.ROFIL)/L
 .BXAI_('*)COPY ',FIL).OQ[2]1
 .BXAI_('*FILTER').OQ[2]1
 .BXAI_('*)ERASE FILTER').OQ[2]1
L:.BXAI_('*)PCOPY APLT2V:SF2VX1 DRIVER').OQ[2]1
 .BXAI_('*DRIVER').OQ[2]1
 .BXAI_('*)OFF HOLD').OQ[2]1
 .BX_('! WORKSPACE ', NAME, ' SETUP COMPLETE').OQ[2]1
 .GO 0
F:T _ ,(4 2 .RO'ASISDABS')[TYP-1;]
 .BXAI_(.BXASCII[65],'APLSF').OQ[2]1
 .BXAI_('*TT',CSET[1;]).OQ[2]1
 .BXAI_('*)MAXCORE 352').OQ[2]1
 .BXAI_('*)LOAD APLT2V:SF2VX4').OQ[2]1
 .GO(0=.ROFIL)/FL
 .BXAI_('*)COPY ',FIL).OQ[2]1
 .BXAI_('*',CSET[2;],T,'FILTER ''',NAME,'''').OQ[2]1
 .BXAI_('*)ERASE ',T,'FILTER').OQ[2]1
FL:.BXAI_('*',CSET[2;],T,'DRIVER ''',NAME,'''').OQ[2]1
 .BXAI_('*)OFF HOLD').OQ[2]1
 .BX_('! ',T,' FILE ', NAME, ' SETUP COMPLETE').OQ[2]1
.DL
 
)SAVE
