#BEGINBUCKET DSNALLOC {JOBNAME}
#/   {LANG}  lower case 2 byte language code from artifact instance XML.

#/   {LANG2BCODE}  upper case 2 byte language code from artifact instance XML.

#/   [MVS2BDSCODE] upper case 2 byte language code, key entry for dataset attributes in MVSDSDataTable.xml

#/   [DSLANGCODE]  upper case 2 byte language code variable which must be set within instance code to resolve 
#/                 
#/
#/ ------------------------------------------------------------------
#BEGINDEFS
#/ ------------------------------------------------------------------
#/EXCEPTIONFORMISSINGSYMBOL
#TABLECALL <MVSDSDATATABLE> KEY:MVS2BDSCODE
#SYMBOLCALLS ENTRY;SYSOUT;CUSTPRODQUAL;TMPUNI;WORKSPC
#/ ------------------------------------------------------------------
#BEGINSTATICINSTANCES
#/ ------------------------------------------------------------------
#STATICINSTANCE MVS2BDSCODE=BZ;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=XC;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=XF;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=XP;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=RC;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=RX;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#STATICINSTANCE MVS2BDSCODE=TE;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#/ We're always going to allocate XX (CNTL.PREEDIT) and we'll copy up the production one.
#/ This would have nasty promotion implications, except that we only use this dataset at
#/ install time, so we don't care.
#STATICINSTANCE MVS2BDSCODE=XX;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#/ -------------------------------------------------
#BEGININSTANCEQUALIFIERS
#/ -------------------------------------------------
#/  Allocated datasets may be referenced *EITHER* as the target of a primary unload, *OR* as the target of
#/  secondary processing following the primary unload. The former is found once in <ENTRY><MVS2BDSCODE>, 
#/  the latter none to many times within <ENTRY><MEMBER><COPY2BDSCODE> 
#IFNOTEQ {PRODUCT} raptor #THEN NOTRAPTOR
#IFNOTEQ {MVS2BDSCODE} XX #THEN NEXT
#INSTANCEUNIQUEKEY OCENNE #NOTUNIQUE NEXT
#STATICINSTANCE MVS2BDSCODE=OC;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#NEXT
#INSTANCEUNIQUEKEY OHENNE #NOTUNIQUE #NOTRAPTOR
#STATICINSTANCE MVS2BDSCODE=OH;LANG2BDSCODE=EN;ENCODE=NE;COPY2BDSCODE=;
#NOTRAPTOR
#IFEQ {ENCODE} [ORDERENCODING] #THEN PASSESENCODE
#IF [INSTALLENCODEDONLY] #THEN DOESNOTQUALIFY
#IFNOTEQ {ENCODE} NE #THEN DOESNOTQUALIFY
#PASSESENCODE
#TABLEFIX <MVSDSDATATABLE> {MVS2BDSCODE}
#IFEQ [NOAL] DoNotAllocate #THEN NEXT
#SET [TARGET2BDSCODE] {MVS2BDSCODE}   
#INSTANCEUNIQUEKEY [TARGET2BDSCODE]{LANG2BCODE}{ENCODE} #NOTUNIQUE NEXT
#CREATEINSTANCEFROMENTRY
#NEXT
#FORALL <MEMBER>
#IFNOT {COPY2BDSCODE} #THEN NEXT
#TABLEFIX <MVSDSDATATABLE> {COPY2BDSCODE}
#SET [TARGET2BDSCODE] {COPY2BDSCODE}
#IFEQ [NOAL] DoNotAllocate #THEN NEXT
#INSTANCEUNIQUEKEY [TARGET2BDSCODE]{LANG2BCODE}{ENCODE} #NOTUNIQUE NEXT
#CREATEINSTANCEFROMENTRY
#NEXT
#ENDFORALL
#DOESNOTQUALIFY
#ENDINSTANCEQUALIFIERS
#/ -------------------------------------------------------------------
#BEGINPREFIX
#/ -------------------------------------------------------------------
#/        Prefix invokes SAS from targeted SAS installation
#SET [SYSNAME] {JOBNAME}  #/ Set SYSNAME variable name to argument value.
#SET [DSLANGCODE] EN         #/ Set language symbol to EN for firing up SAS
[JOBCARD1]
[JOBCARD2]
[JOBCARD3]
[JOBCARD4]
[JOBCARD5]
//STGALLOC EXEC PGM=[ENTRY],                       
//  PARM=('SETINIT MSGCASE CAPSOUT ERRORABEND NOWORKTERM',     
//        'MACRO ERRORCHECK=STRICT SASUSER=WORK')
#TABLEFIX <MVSDSDATATABLE> LD  #/ Load Library
//STEPLIB  DD DISP=SHR,                                        
//  DSN=[CUSTPRODQUAL].[LOQUAL]                                       
#TABLEFIX <MVSDSDATATABLE> SH  #/ Sashelp
//[DFLTDDN]  DD DISP=SHR,                                        
//  DSN=[CUSTPRODQUAL].[LOQUAL]                                       
#TABLEFIX <MVSDSDATATABLE> AU  #/ Autocalls
//[DFLTDDN] DD DISP=SHR,                                        
//  DSN=[CUSTPRODQUAL].[LOQUAL]                                        
#TABLEFIX <MVSDSDATATABLE> SM  #/ SAS messages
//[DFLTDDN] DD DISP=SHR,                                        
//  DSN=[CUSTPRODQUAL].[LOQUAL]                                        
//WORK     DD UNIT=[TMPUNI],SPACE=(6144,([WORKSPC])),          
//         DCB=(RECFM=FS,LRECL=6144,BLKSIZE=6144)              
//SASLOG   DD SYSOUT=[SYSOUT]                                  
//SASCLOG  DD SYSOUT=[SYSOUT]                                  
//CONFIG   DD DISP=SHR,  #/ Using configuration file for install, not customer's
//         DSN=[CNTLDSN]($CFGINST)                             
//SASLIST  DD SYSOUT=[SYSOUT]                                  
//SASPARM  DD UNIT=[TMPUNI],SPACE=(400,(100,300)),             
//         DCB=(RECFM=FB,LRECL=80,BLKSIZE=400,BUFNO=1)         
//SYSIN  DD DATA,DLM='!1'  #/ Begin source code stream for SAS session. Delimiter is !^ in column 1 of line
options filestat symbolgen mprint mlogic;
%macro dsnq;               #/ Invoke SAS macro compiler.

#/ --------------------------------------------------------------------
#BEGININSTANCE               #/ All instance code must resolve to valid SAS source code.
#/ -------------------------------------------------------------------
#SET [DSLANGCODE] EN         #/ Set language symbol to EN for empty/blank language argument.
#IFNOT {LANG2BCODE} #THEN NEXT     #/ Is language symbol non-blank?
#SET [DSLANGCODE] {LANG2BCODE}     #/ If so set general use language symbol to instance argument value. 
#NEXT
#SET [MVSDSCODE] {MVS2BDSCODE}
#TABLEFIX <MVSDSDATATABLE> [MVSDSCODE] #/ Fix ds table row to OTP2 from the instance.
#IFNOT [ALIASTO] #THEN NOALIAS #/ See if it's marked alias in ds table, if not then skip 
#SET [MVSDSCODE] [ALIASTO]     #/ Hold the aliased ds from the table row
#TABLEFIX <MVSDSDATATABLE> [MVSDSCODE]  #/ Reset the table row to the aliased OTP2.
#NOALIAS
#IF [NOSAL] #THEN ALLOCATEATPRODUCTION  #/ Check whether dataset is staged at all and branch if not
 dsnexst '[CUSTPRODQUAL][STAGEQUAL].[LOQUAL]';  #/ Query whether dataset already exists. 
#IFNOTEQ [DATASETTYPE] SASDATALIB #THEN ALLOCFILENAME  #/ Allocate libname or filename?
 libname [OUTPDDNAME] '[CUSTPRODQUAL][STAGEQUAL].[LOQUAL]' #/ Allocate libname 
#THEN GOCHECK
#ALLOCFILENAME
 filename [OUTPDDNAME] '[CUSTPRODQUAL][STAGEQUAL].[LOQUAL]' #/ Allocate filename
#THEN GOCHECK
#ALLOCATEATPRODUCTION
 dsnexst '[CUSTPRODQUAL].[LOQUAL]';  #/ Query whether dataset already exists. 
#IFNOTEQ [DATASETTYPE] SASDATALIB #THEN ALLOCFILENAME  #/ Allocate libname or filename?
 libname [OUTPDDNAME] '[CUSTPRODQUAL].[LOQUAL]' #/ Allocat libname 
#THEN GOCHECK
#ALLOCFILENAME
 filename [OUTPDDNAME] '[CUSTPRODQUAL].[LOQUAL]' #/ Allocat filename
#GOCHECK  
%if &sysdexst %then %do;  #/ does this dataset already exist?
     disp=old;            #/ if so then allocate disposition=old
%end;
%else %do;   #/ otherwise do rest of this to create dataset from scratch
disp=(new,catlg,delete) blksize=[BLKSIZE]                     
space=[SPACEPARMS]                              
#IFEQ [DATASETTYPE] SASDATALIB #THEN NEXT                
#IF [LRECL] #THEN RECFMNOTU    #/ lrecl of null means ds unformated, otherwise needs dsorg, recfm parms                 
dsorg=[DSORG] recfm=[RECFM]    #/ unformatted, dsorg recfm only. Do not specify unused parms.              
#IFNOT #THEN NEXT                           
#RECFMNOTU                                  
dsorg=[DSORG] recfm=[RECFM] lrecl=[LRECL]  #/ formatted, dsorg recfm lrecl      
#NEXT                                       
#IFNOTEQ [DATASETTYPE] PDS #THEN NEXT
DSNTYPE=PDS            #/ Specify dataset is a PDS                     
#NEXT                                       
#IFNOTEQ [DATASETTYPE] PDSE #THEN NEXT
DSNTYPE=LIBRARY        #/ Specify dataset is a PDSE       
#NEXT                                       
#IF [SMS-ALLOC] #THEN SMSALLOC   #/ branch to section if customer using IBM SMS to manage storage     
#IFNOT [VOLSER] #THEN NOVSER  #/ if volser has resolved to null, then branch.              
#IF [TMPDS] #THEN TMPU #/ if this is a pre-allocated dataset deleted after the install then branch         
UNIT=[DISKUNIT] VOLSER='[BYDSVOLSER]';   #/ having volser by dataset allows splitting installation storage        
#THEN NEND                           
#NOVSER                                     
#IF [TMPDS] #THEN TMPU
UNIT=[DISKUNIT];     #/ set unit to permanent diskunit                          
#THEN NEND                           
#TMPU                                       
UNIT=[TMPUNI];       #/ set unit to temporary diskunit                      
#THEN NEND                           
#SMSALLOC            #/ section for IBM SMS managed storage class specifications                           
#IFNOT [SMS-STORCLAS] #THEN NXCLS           
STORCLAS=[SMS-STORCLAS]              #/ STORCLAS keyword, if used       
#NXCLS                                      
#IFNOT [SMS-MGMTCLAS] #THEN NXCLS           
MGMTCLAS=[SMS-MGMTCLAS]              #/ MGMTCLAS keyword, if used 
#NXCLS                                      
#IFNOT [SMS-DATACLAS] #THEN NXCLS           
DATACLAS=[SMS-DATACLAS]              #/ DATACLAS keyword, if used
#NXCLS                                      
UNIT=[DISKUNIT];              #/ hard set to permanent diskunit, SMS not used for temps        
#NEND                                       
#IFNOTEQ [DATASETTYPE] SASDATALIB #THEN NEXT  #/ skip section if wasn't allocated as libname             
PROC CONTENTS DATA=[OUTPDDNAME]._ALL_ NOPRINT;  #/ this section "touches" new datalib so all the 
DATA [OUTPDDNAME].NODATA_NULLDATA;             #/ internal markers are set up for a later open in SAS   
X=0;PUT X; RUN;                                #/ avoids "not initialized" error
#NEXT                                       
%END;                                                      
#/ ----------------------------------------------------------------------
#BEGINSUFFIX 
#/ -------------------------------------------------------------------
%mend dsnq; %dsnq             #/ close SAS macro, invoke SAS macro once.
!1                           #/ Delimiter for SAS session SYSIN definition. 
//
#/ ----------------------------------------------------------------------
#ENDBUCKET DSNALLOCSTG