mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-14 01:50:06 +00:00
version 20200619
version 20200619
Fixes:
Note about type conversion fixed, testing HELP tags improved, documentation elements added.
Features:
IMLMODULE element added to the list of elements. IML modules can be now added to the package and are stored in "<PackagNamie>IML" catalog in the WORK library.
This commit is contained in:
@@ -36,7 +36,7 @@
|
|||||||
*/
|
*/
|
||||||
/**#############################################################################**/
|
/**#############################################################################**/
|
||||||
|
|
||||||
/* Macros to generate SAS packages, version 20200610 */
|
/* Macros to generate SAS packages, version 20200619 */
|
||||||
/* A SAS package is a zip file containing a group
|
/* A SAS package is a zip file containing a group
|
||||||
of SAS codes (macros, functions, datasteps generating
|
of SAS codes (macros, functions, datasteps generating
|
||||||
data, etc.) wrapped up together and %INCLUDEed by
|
data, etc.) wrapped up together and %INCLUDEed by
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
%put # This is short help information for the generatePackage macro #;
|
%put # This is short help information for the generatePackage macro #;
|
||||||
%put ###############################################################################;
|
%put ###############################################################################;
|
||||||
%put # #;
|
%put # #;
|
||||||
%put # Macro to generate SAS packages, version 20200610 #;
|
%put # Macro to generate SAS packages, version 20200619 #;
|
||||||
%put # #;
|
%put # #;
|
||||||
%put # A SAS package is a zip file containing a group #;
|
%put # A SAS package is a zip file containing a group #;
|
||||||
%put # of SAS codes (macros, functions, datasteps generating #;
|
%put # of SAS codes (macros, functions, datasteps generating #;
|
||||||
@@ -276,34 +276,39 @@ DESCRIPTION END:
|
|||||||
| | option INLIB= should be: work.&packageName.fcmp
|
| | option INLIB= should be: work.&packageName.fcmp
|
||||||
| | (both literally with macrovariable name and "fcmp" sufix)]
|
| | (both literally with macrovariable name and "fcmp" sufix)]
|
||||||
| |
|
| |
|
||||||
| +-efg.sas [a file with a code creating function EFG]
|
| +-efg.sas [a file with a code creating function EFG, _with_ "Proc FCMP" header]
|
||||||
|
|
|
|
||||||
+-003_format [one file one format,
|
+-003_functions [mind the S at the end!, one file one function,
|
||||||
|
| | only plain code of the function, without "Proc FCMP" header]
|
||||||
|
| |
|
||||||
|
| +-ijk.sas [a file with a code creating function EFG, _without_ "Proc FCMP" header]
|
||||||
|
|
|
||||||
|
+-004_format [one file one format,
|
||||||
| | option LIB= should be: work.&packageName.format
|
| | option LIB= should be: work.&packageName.format
|
||||||
| | (literally with macrovariable name and "format" sufix)]
|
| | (literally with macrovariable name and "format" sufix)]
|
||||||
| |
|
| |
|
||||||
| +-efg.sas [a file with a code creating format EFG and informat EFG]
|
| +-efg.sas [a file with a code creating format EFG and informat EFG]
|
||||||
|
|
|
|
||||||
+-004_data [one file one dataset]
|
+-005_data [one file one dataset]
|
||||||
| |
|
| |
|
||||||
| +-abc.efg.sas [a file with a code creating dataset EFG in library ABC]
|
| +-abc.efg.sas [a file with a code creating dataset EFG in library ABC]
|
||||||
|
|
|
|
||||||
+-005_exec [so called "free code", content of the files will be printed
|
+-006_exec [so called "free code", content of the files will be printed
|
||||||
| | to the log before execution]
|
| | to the log before execution]
|
||||||
| |
|
| |
|
||||||
| +-<no file, in this case folder may be skipped>
|
| +-<no file, in this case folder may be skipped>
|
||||||
|
|
|
|
||||||
+-006_format [if your codes depend each other you can order them in folders,
|
+-007_format [if your codes depend each other you can order them in folders,
|
||||||
| | e.g. code from 003_... will be executed before 006_...]
|
| | e.g. code from 003_... will be executed before 006_...]
|
||||||
| |
|
| |
|
||||||
| +-abc.sas [a file with a code creating format ABC,
|
| +-abc.sas [a file with a code creating format ABC,
|
||||||
| used in the definition of the format EFG]
|
| used in the definition of the format EFG]
|
||||||
+-007_function
|
+-008_function
|
||||||
| |
|
| |
|
||||||
| +-<no file, in this case folder may be skipped>
|
| +-<no file, in this case folder may be skipped>
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
+-008_lazydata [one file one dataset]
|
+-009_lazydata [one file one dataset]
|
||||||
| |
|
| |
|
||||||
| +-klm.sas [a file with a code creating dataset klm in library work
|
| +-klm.sas [a file with a code creating dataset klm in library work
|
||||||
| it will be created only if user request it by using:
|
| it will be created only if user request it by using:
|
||||||
@@ -311,6 +316,11 @@ DESCRIPTION END:
|
|||||||
| multiple elements separated by space are allowed
|
| multiple elements separated by space are allowed
|
||||||
| an asterisk(*) means "load all data"]
|
| an asterisk(*) means "load all data"]
|
||||||
|
|
|
|
||||||
|
+-010_imlmodule [one file one IML module,
|
||||||
|
| | only plain code of the module, without "Proc IML" header]
|
||||||
|
| |
|
||||||
|
| +-abc.sas [a file with a code creating IML module ABC, _without_ "Proc IML" header]
|
||||||
|
|
|
||||||
+-<sequential number>_<type [in lower case]>
|
+-<sequential number>_<type [in lower case]>
|
||||||
|
|
|
|
||||||
+-...
|
+-...
|
||||||
@@ -681,7 +691,7 @@ data _null_;
|
|||||||
put ' do _N_ = 1 to countw(SYSloadedPackages); ';
|
put ' do _N_ = 1 to countw(SYSloadedPackages); ';
|
||||||
put ' req = scan(SYSloadedPackages, _N_, " "); ';
|
put ' req = scan(SYSloadedPackages, _N_, " "); ';
|
||||||
put ' name = lowcase(strip(scan(req, 1, "("))); ';
|
put ' name = lowcase(strip(scan(req, 1, "("))); ';
|
||||||
put ' vers = input(compress(scan(req,-1, "("), ".", "KD"),best32.); ';
|
put ' vers = input(compress(scan(req,-1, "("), ".", "KD"), best32.); ';
|
||||||
put ' _RC_ = LP.add(); ';
|
put ' _RC_ = LP.add(); ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
|
|
||||||
@@ -706,7 +716,7 @@ data _null_;
|
|||||||
put ' call symputX("packageRequiredErrors", 1, "L"); ';
|
put ' call symputX("packageRequiredErrors", 1, "L"); ';
|
||||||
put ' do req = ' / packageReqPackages / ' ; ';
|
put ' do req = ' / packageReqPackages / ' ; ';
|
||||||
put ' name = lowcase(strip(scan(req, 1, "("))); ';
|
put ' name = lowcase(strip(scan(req, 1, "("))); ';
|
||||||
put ' vers = lowcase(compress(scan(req,-1, "("), ".", "KD")); ';
|
put ' vers = input(compress(scan(req,-1, "("), ".", "KD"), best32.); ';
|
||||||
put ' put "ERROR: SAS package " req "is missing! Download it and" ; ';
|
put ' put "ERROR: SAS package " req "is missing! Download it and" ; ';
|
||||||
put ' put ''ERROR- use %loadPackage('' name ", requiredVersion = " vers ") to load it." ; ';
|
put ' put ''ERROR- use %loadPackage('' name ", requiredVersion = " vers ") to load it." ; ';
|
||||||
put ' end ; ';
|
put ' end ; ';
|
||||||
@@ -739,7 +749,9 @@ data _null_;
|
|||||||
test files are used only during package generation
|
test files are used only during package generation
|
||||||
*/
|
*/
|
||||||
/* test for supported types */
|
/* test for supported types */
|
||||||
if not (upcase(type) in: ('LIBNAME' 'MACRO' 'DATA' 'FUNCTION' /*'FUNCTIONS'*/ 'FORMAT' 'EXEC' 'CLEAN' 'LAZYDATA' 'TEST')) then
|
if not (upcase(type) in:
|
||||||
|
('LIBNAME' 'MACRO' 'DATA' 'FUNCTION' /*'FUNCTIONS'*/ 'FORMAT' 'IMLMODULE' 'EXEC' 'CLEAN' 'LAZYDATA' 'TEST'))
|
||||||
|
then
|
||||||
do;
|
do;
|
||||||
putlog 'WARNING: Type ' type 'is not yet supported.';
|
putlog 'WARNING: Type ' type 'is not yet supported.';
|
||||||
continue;
|
continue;
|
||||||
@@ -761,17 +773,30 @@ data _null_;
|
|||||||
put '%put NOTE- ;';
|
put '%put NOTE- ;';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if 1 = FIRST.type and upcase(type)='FUNCTIONS' then /* for multiple functions in one FCMP run */
|
/* HEADERS for IML and FCMP */
|
||||||
|
if 1 = FIRST.type and upcase(type)='FUNCTIONS' then /* header, for multiple functions in one FCMP run */
|
||||||
do;
|
do;
|
||||||
put "proc fcmp outlib = work.%lowcase(&packageName.fcmp).package; ";
|
put "proc fcmp outlib = work.%lowcase(&packageName.fcmp).package; ";
|
||||||
end;
|
end;
|
||||||
|
if 1 = FIRST.type and upcase(type)='IMLMODULE' then /* header, for IML modules */
|
||||||
|
do;
|
||||||
|
put "proc iml; ";
|
||||||
|
end;
|
||||||
|
|
||||||
|
/* include the file with the code of the element */
|
||||||
put '%include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;' /;
|
put '%include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;' /;
|
||||||
|
|
||||||
if 1 = LAST.type and upcase(type)='FUNCTIONS' then /* for multiple functions in one FCMP run */
|
/* FOOTERS for IML and FCMP */
|
||||||
|
if 1 = LAST.type and upcase(type)='FUNCTIONS' then /* footer, for multiple functions in one FCMP run */
|
||||||
do;
|
do;
|
||||||
put "run; ";
|
put "run; ";
|
||||||
end;
|
end;
|
||||||
|
if 1 = LAST.type and upcase(type)='IMLMODULE' then /* footer, for IML modules */
|
||||||
|
do;
|
||||||
|
put "reset storage = WORK.&packageName.IML; "; /* set the storage location for modules */
|
||||||
|
put "store module = _ALL_; "; /* and store all created modules */
|
||||||
|
put "quit; ";
|
||||||
|
end;
|
||||||
|
|
||||||
isFunction + (upcase(type)=:'FUNCTION');
|
isFunction + (upcase(type)=:'FUNCTION');
|
||||||
isFormat + (upcase(type)=:'FORMAT');
|
isFormat + (upcase(type)=:'FORMAT');
|
||||||
@@ -1007,6 +1032,22 @@ data _null_;
|
|||||||
put '%put; %put NOTE:[CMPLIB] %sysfunc(getoption(cmplib));' /;
|
put '%put; %put NOTE:[CMPLIB] %sysfunc(getoption(cmplib));' /;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
/* delete IML modules */
|
||||||
|
EOF = 0; first.IML = 1;
|
||||||
|
do until(EOF);
|
||||||
|
set &filesWithCodes. end = EOF;
|
||||||
|
if not (upcase(type)=:'IMLMODULE') then continue;
|
||||||
|
if first.iml then
|
||||||
|
do;
|
||||||
|
put "proc delete lib=WORK data=&packageName.IML (memtype=catalog); ";
|
||||||
|
put "run; ";
|
||||||
|
first.IML = 0;
|
||||||
|
end;
|
||||||
|
put '%put NOTE- Element of type ' type 'generated from the file "' file +(-1) '" will be deleted;';
|
||||||
|
put '%put NOTE- ;' /;
|
||||||
|
/* put 'remove module = ' fileshort ';'; */
|
||||||
|
end;
|
||||||
|
|
||||||
/* delete datasets */
|
/* delete datasets */
|
||||||
put "proc sql noprint;";
|
put "proc sql noprint;";
|
||||||
EOF = 0;
|
EOF = 0;
|
||||||
@@ -1149,7 +1190,7 @@ data _null_;
|
|||||||
put ' end ; ';
|
put ' end ; ';
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
put 'put "***"; put "* SAS package generated by generatePackage, version 20200610 *"; put "***";';
|
put 'put "***"; put "* SAS package generated by generatePackage, version 20200619 *"; put "***";';
|
||||||
|
|
||||||
put 'run; ' /;
|
put 'run; ' /;
|
||||||
|
|
||||||
@@ -1203,33 +1244,35 @@ data _null_;
|
|||||||
put 'run;';
|
put 'run;';
|
||||||
*/
|
*/
|
||||||
/* loop through content found and print info to the log */
|
/* loop through content found and print info to the log */
|
||||||
put 'data _null_; ';
|
put 'data _null_; ';
|
||||||
put 'if upcase(strip(symget("helpKeyword"))) in (" " "LICENSE") then do; stop; end; ';
|
put 'if upcase(strip(symget("helpKeyword"))) in (" " "LICENSE") then do; stop; end; ';
|
||||||
put 'if NOBS = 0 then do; ' /
|
put 'if NOBS = 0 then do; ' /
|
||||||
'put; put '' *> No help info found. Try %helpPackage(packageName,*) to display all.''; put; stop; ' /
|
'put; put '' *> No help info found. Try %helpPackage(packageName,*) to display all.''; put; stop; ' /
|
||||||
'end; ';
|
'end; ';
|
||||||
put ' do until(EOFDS); ';
|
put ' do until(EOFDS); ';
|
||||||
put ' set WORK._last_ end = EOFDS nobs = NOBS; ';
|
put ' set WORK._last_ end = EOFDS nobs = NOBS; ';
|
||||||
put ' length memberX $ 1024; ';
|
put ' length memberX $ 1024; ';
|
||||||
put ' memberX = cats("_",folder,".",file); ';
|
put ' memberX = cats("_",folder,".",file); ';
|
||||||
/* inner datastep in call execute to read each embedded file */
|
/* inner datastep in call execute to read each embedded file */
|
||||||
put ' call execute("data _null_; ");';
|
put ' call execute("data _null_; ");';
|
||||||
put " call execute('infile &_PackageFileref_.(' || strip(memberX) || ') end = EOF; ');";
|
put " call execute('infile &_PackageFileref_.(' || strip(memberX) || ') end = EOF; ');";
|
||||||
put ' call execute(" printer = 0; ");';
|
put ' call execute(" printer = 0; ");';
|
||||||
put ' call execute(" do until(EOF); ");';
|
put ' call execute(" do until(EOF); ");';
|
||||||
put ' call execute(" input; ");';
|
put ' call execute(" input; ");';
|
||||||
put ' call execute(" if strip(_infile_) = cat(""/"",""*** "",""HELP END"","" ***"",""/"") then printer = 0; ");'; /* it looks like that because of comments */
|
put ' call execute(" if upcase(strip(_infile_)) ';
|
||||||
put ' call execute(" if printer then put ""*> "" _infile_; ");';
|
put ' = cat(""/"",""*** "",""HELP END"","" ***"",""/"") then printer = 0; ");'; /* it looks like that because of comments */
|
||||||
put ' call execute(" if strip(_infile_) = cat(""/"",""*** "",""HELP START"","" ***"",""/"") then printer = 1; ");'; /* it looks like that because of comments */
|
put ' call execute(" if printer then put ""*> "" _infile_; ");';
|
||||||
put ' call execute(" end; ");';
|
put ' call execute(" if upcase(strip(_infile_)) ';
|
||||||
put ' call execute(" put ""*> "" / ""*> ""; ");';
|
put ' = cat(""/"",""*** "",""HELP START"","" ***"",""/"") then printer = 1; ");'; /* it looks like that because of comments */
|
||||||
put ' call execute(" stop; ");';
|
put ' call execute(" end; ");';
|
||||||
put ' call execute("run; ");';
|
put ' call execute(" put ""*> "" / ""*> ""; ");';
|
||||||
put ' if lowcase(type) =: "data" then ';
|
put ' call execute(" stop; ");';
|
||||||
put ' do; ';
|
put ' call execute("run; ");';
|
||||||
put ' call execute("title ""Dataset " || strip(fileshort) || " from package &packageName. ""; ");';
|
put ' if lowcase(type) =: "data" then ';
|
||||||
put ' call execute("proc contents data = " || strip(fileshort) || "; run; title; ");';
|
put ' do; ';
|
||||||
put ' end; ';
|
put ' call execute("title ""Dataset " || strip(fileshort) || " from package &packageName. ""; ");';
|
||||||
|
put ' call execute("proc contents data = " || strip(fileshort) || "; run; title; ");';
|
||||||
|
put ' end; ';
|
||||||
/**/
|
/**/
|
||||||
put " end; ";
|
put " end; ";
|
||||||
put " stop; ";
|
put " stop; ";
|
||||||
@@ -1266,8 +1309,8 @@ data _null_;
|
|||||||
call execute(' retain test .;');
|
call execute(' retain test .;');
|
||||||
call execute(' infile _IN_ lrecl=32767 dlm="0a0d"x end=EOF;');
|
call execute(' infile _IN_ lrecl=32767 dlm="0a0d"x end=EOF;');
|
||||||
call execute(' input;');
|
call execute(' input;');
|
||||||
call execute(' if strip(_infile_) = cat("/","*** ","HELP START"," ***","/") then test + (+1); ');
|
call execute(' if upcase(strip(_infile_)) = cat("/","*** ","HELP START"," ***","/") then test + (+1); ');
|
||||||
call execute(' if strip(_infile_) = cat("/","*** ","HELP END", " ***","/") then test + (-1); ');
|
call execute(' if upcase(strip(_infile_)) = cat("/","*** ","HELP END", " ***","/") then test + (-1); ');
|
||||||
call execute(' if (test not in (.,0,1)) or (EOF and test) then ');
|
call execute(' if (test not in (.,0,1)) or (EOF and test) then ');
|
||||||
call execute(' do; ');
|
call execute(' do; ');
|
||||||
call execute(' put "ERR" "OR: unmatching or nested HELP tags!" _N_=; ');
|
call execute(' put "ERR" "OR: unmatching or nested HELP tags!" _N_=; ');
|
||||||
|
|||||||
Reference in New Issue
Block a user