mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2025-12-15 21:14:34 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e47ab5e37 | ||
|
|
c4e21e86b6 | ||
|
|
006377b255 | ||
|
|
4b640e8ce1 | ||
|
|
7a7f674acf | ||
|
|
c667bc6b25 | ||
|
|
0a01f39662 |
19
README.md
19
README.md
@@ -16,7 +16,7 @@ Don't forget to **STAR** (:star:) the repository! :-)
|
||||
|
||||
### Current version:
|
||||
|
||||
**The latest version** of SPF is **`20240927`**.
|
||||
**The latest version** of SPF is **`20241207`**.
|
||||
|
||||
To get started with SAS Packages try this [**`Getting Started with SAS Packages`**](https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/Documentation/Getting_Started_with_SAS_Packages.pdf "Getting Started with SAS Packages") presentation (see the `./SPF/Documentation` directory).
|
||||
|
||||
@@ -51,7 +51,8 @@ Letter "D" indicates tutorial dedicated for developers and "U" materials for use
|
||||
|
||||
3) (D) Article and all required materials for ["My first SAS Package"](https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation/Paper_1079-2021) tutorial.
|
||||
|
||||
4) (DU) Materials from Hands-on-Workshop (4+ hours) tutorial: [Share your code with SAS Packages](https://github.com/yabwon/HoW-SASPackages).
|
||||
4) (DU) Materials from Hands-on-Workshop (4+ hours) tutorial: [Share your code with SAS Packages](https://github.com/yabwon/HoW-SASPackages).
|
||||
It is a "zero to hero" tutorial that explains all the "bells and whistles" of using, and all the "nuts and bolts" of developing SAS packages.
|
||||
|
||||
|
||||
---
|
||||
@@ -163,6 +164,10 @@ The SAS Packages Framework [(short) documentation](https://github.com/yabwon/SAS
|
||||
|
||||
### Updates worth mentioning:
|
||||
|
||||
**Update**\[October 27th, 2024\]**:** `%splitCodeForPackage()` **utility macro is available. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241027 "splitCodeForPackage"))**.
|
||||
|
||||
**Update**\[October 14th, 2024\]**:** `DS2PCK` and `DS2THR` **types for `PROC DS2` *threads* and *packages* added to the framework. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241014 "PROC DS2"))**.
|
||||
|
||||
**Update**\[December 10th, 2023\]**:** `markdownDoc=` **parameter added to** `%generatePackage()` **macro, which allows to generate markdown file with documentation. Content is taken from the help information notes and the description. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20231210 "markdown documentation"))**.
|
||||
|
||||
**Update**\[November 11th, 2023\]**:** `KMFSNIP` **type for *key macro abbreviations* snippets added to the framework. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20231111 "KMF-abbreviations"))**.
|
||||
@@ -215,32 +220,32 @@ Packages:
|
||||
|
||||
- **SQLinDS**
|
||||
|
||||
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
|
||||
[SQLinDS in SASPAC](https://github.com/SASPAC/sqlinds "SQLinDS in SASPAC")
|
||||
|
||||
|
||||
- **DFA** (Dynamic Function Arrays)
|
||||
|
||||
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
|
||||
[Documentation for DFA](https://github.com/SASPAC/blob/main/dfa.md "Documentation for DFA")
|
||||
|
||||
[DFA in SASPAC](https://github.com/SASPAC/dfa "DFA in SASPAC")
|
||||
|
||||
- **macroArray**
|
||||
|
||||
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
|
||||
[Documentation for macroArray](https://github.com/SASPAC/blob/main/macroarray.md "Documentation for macroArray")
|
||||
|
||||
[MacroArray in SASPAC](https://github.com/SASPAC/macroarray "MacroArray in SASPAC")
|
||||
|
||||
- **BasePlus**
|
||||
|
||||
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
|
||||
[BasePlus in SASPAC](https://github.com/SASPAC/baseplus "BasePlus in SASPAC")
|
||||
|
||||
- **GSM** (Generate Secure Macros)
|
||||
|
||||
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
|
||||
[Documentation for GSM](https://github.com/SASPAC/blob/main/gsm.md "Documentation for GSM")
|
||||
|
||||
[GSM in SASPAC](https://github.com/SASPAC/gsm "GSM in SASPAC")
|
||||
|
||||
|
||||
BIN
SPF/Documentation/Paper_SM01-PHUSEEU2024.pdf
Normal file
BIN
SPF/Documentation/Paper_SM01-PHUSEEU2024.pdf
Normal file
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
when empty the "packages" value is used */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to list directories pointed by "packages" fileref, version 20240927. Run %extendPackagesFileref(HELP) for help info.'
|
||||
des = 'Macro to list directories pointed by "packages" fileref, version 20241207. Run %extendPackagesFileref(HELP) for help info.'
|
||||
;
|
||||
|
||||
%if %QUPCASE(&packages.) = HELP %then
|
||||
@@ -22,7 +22,7 @@ des = 'Macro to list directories pointed by "packages" fileref, version 20240927
|
||||
%put ### This is short help information for the `extendPackagesFileref` macro #;
|
||||
%put #-----------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to list directories pointed by 'packages' fileref, version `20240927` #;
|
||||
%put # Macro to list directories pointed by 'packages' fileref, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -56,7 +56,7 @@ des = 'Macro to list directories pointed by "packages" fileref, version 20240927
|
||||
%put # Run the following code in your SAS session: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put %nrstr( filename packages ("C:/SAS_PK1" "C:/SAS_PK2"); %%* setup a directory for packages; );
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put ;
|
||||
%put %nrstr( filename packages ("D:/NEW_DIR" %%extendPackagesFileref()); %%* add new directory; );
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Macro to generate SAS packages.
|
||||
|
||||
Version 20240927
|
||||
Version 20241207
|
||||
|
||||
A SAS package is a zip file containing a group
|
||||
of SAS codes (macros, functions, data steps generating
|
||||
@@ -43,7 +43,7 @@
|
||||
file name be created */
|
||||
)/ secure minoperator
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to generate SAS packages, version 20240927. Run %generatePackage() for help info.'
|
||||
des = 'Macro to generate SAS packages, version 20241207. Run %generatePackage() for help info.'
|
||||
;
|
||||
%if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then
|
||||
%do;
|
||||
@@ -58,7 +58,7 @@ des = 'Macro to generate SAS packages, version 20240927. Run %generatePackage()
|
||||
%put ### This is short help information for the `generatePackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to generate SAS packages, version `20240927` #;
|
||||
%put # Macro to generate SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -434,7 +434,7 @@ Maintainer: Firstname Lastname (xxxxxx@yyyyy.com)
|
||||
License: MIT
|
||||
Encoding: UTF8
|
||||
|
||||
Required: "Base SAS Software" :%*optional, COMMA separated, QUOTED list, names of required SAS products, values must be like from proc setinit;run; output *;
|
||||
Required: "Base SAS Software" :%*optional, COMMA separated, QUOTED list, names of required SAS products, values must be like from "proc setinit" output *;
|
||||
ReqPackages: "macroArray (0.1)", "DFA (0.1)" :%*optional, COMMA separated, QUOTED list, names of required packages *;
|
||||
|
||||
>> **DESCRIPTION** <<
|
||||
@@ -510,7 +510,7 @@ DESCRIPTION END:
|
||||
| it will be created only if user request it by using:
|
||||
| %loadPackage(packagename, lazyData=klm)
|
||||
| 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]
|
||||
@@ -527,6 +527,18 @@ DESCRIPTION END:
|
||||
| |
|
||||
| +-abc.sas [a file with a KMF-abbreviation snippet ABC, _with_ proper tagging, snippets names are in low-case]
|
||||
|
|
||||
+-013_ds2pck [one file one PROC DS2 package]
|
||||
| |
|
||||
| +-abc.sas [a data set with a package ABC stored in WORK.ABC data set]
|
||||
| |
|
||||
| +-library.xyz.sas [a data set with a package LIBRARY.XYZ stored in LIBRARY.XYZ data set]
|
||||
|
|
||||
+-014_ds2thr [one file one PROC DS2 thread]
|
||||
| |
|
||||
| +-abc.sas [a data set with a thread ABC stored in WORK.ABC data set]
|
||||
| |
|
||||
| +-library.xyz.sas [a data set with a thread LIBRARY.XYZ stored in LIBRARY.XYZ data set]
|
||||
|
|
||||
+-<sequential number>_<type [in lower case]>
|
||||
|
|
||||
+-00n_clean [if you need to clean something up after exec file execution,
|
||||
@@ -609,6 +621,7 @@ data &filesWithCodes.;
|
||||
'IMLMODULE' 'PROTO' 'EXEC' 'CLEAN'
|
||||
'LAZYDATA' 'TEST' 'CASLUDF'
|
||||
'ADDCNT' 'KMFSNIP'
|
||||
'DS2PCK' 'DS2THR'
|
||||
))
|
||||
then
|
||||
do;
|
||||
@@ -687,6 +700,9 @@ run;
|
||||
%let notesSourceOptions = %sysfunc(getoption(notes)) %sysfunc(getoption(source));
|
||||
options NOnotes NOsource;
|
||||
|
||||
options mprint;
|
||||
options notes source;
|
||||
|
||||
proc sort data = &filesWithCodes.;
|
||||
by order type file;
|
||||
run;
|
||||
@@ -793,7 +809,7 @@ run;
|
||||
/* code inspired by Kurt Bremser's "Talking to Your Host" article */
|
||||
/* https://communities.sas.com/t5/SAS-User-Groups-Library/WUSS-Presentation-Talking-to-Your-Host/ta-p/838344 */
|
||||
/* WUSS 2022 */
|
||||
|
||||
|
||||
data &filesWithCodes.addCnt;
|
||||
run;
|
||||
|
||||
@@ -855,9 +871,12 @@ title6 "MD5 hashed fileref of package lowcase name: &_PackageFileref_.";
|
||||
title8 "Required SAS packages: %qsysfunc(compress(%superq(packageReqPackages),%str(%'%")))" ; /* " */
|
||||
%end;
|
||||
|
||||
footnote1 "SAS Packages Framework, version 20240927";
|
||||
footnote1 "SAS Packages Framework, version 20241207";
|
||||
|
||||
proc print data = &filesWithCodes.(drop=base folderRef fileRef rc folderid _abort_ fileId additionalContent);
|
||||
proc print
|
||||
data = &filesWithCodes.(drop=base folderRef fileRef rc folderid _abort_ fileId additionalContent)
|
||||
width=full
|
||||
;
|
||||
run;
|
||||
title;
|
||||
|
||||
@@ -876,7 +895,7 @@ title;
|
||||
title2 "Package additional content:";
|
||||
proc print
|
||||
data=&filesWithCodes.addCnt(drop=root dir level)
|
||||
label
|
||||
label width=full
|
||||
;
|
||||
run;
|
||||
%end;
|
||||
@@ -1029,22 +1048,35 @@ data _null_;
|
||||
put ' filename &_PackageFileref_. clear; ';
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
put ' %local rV pV; ';
|
||||
put ' %let pV = %sysfunc(compress(&packageVersion.,.,kd)); ';
|
||||
put ' %let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&pV.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&pV.,3,.,M)+0)*1e0); ';
|
||||
put ' %let rV = %sysfunc(compress(&requiredVersion.,.,kd)); ';
|
||||
put ' %let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&rV.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&rV.,3,.,M)+0)*1e0); ';
|
||||
put ' %if %sysevalf(&requiredVersion. > &packageVersion.) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put ERROR: Required version is &requiredVersion.; ';
|
||||
put ' %put ERROR- Provided version is &packageVersion.; ';
|
||||
put ' %GOTO WrongVersionOFPackage; /*%RETURN;*/ ';
|
||||
put ' %local rV pV rV0 pV0 rVsign; ';
|
||||
put ' %let pV0 = %sysfunc(compress(&packageVersion.,.,kd)); ';
|
||||
put ' %let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&pV0.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&pV0.,3,.,M)+0)*1e0); ';
|
||||
put ' ';
|
||||
put ' %let rV0 = %sysfunc(compress(&requiredVersion.,.,kd)); ';
|
||||
put ' %let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k)); ';
|
||||
put ' %if %superq(rVsign)= %then %let rVsign=<=; ';
|
||||
put ' %else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.; ';
|
||||
put ' %put WARNING- Supported operators are: %str(= <= =< => >= < >); ';
|
||||
put ' %let rVsign=<=; ';
|
||||
put ' %end; ';
|
||||
put ' %let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&rV0.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&rV0.,3,.,M)+0)*1e0); ';
|
||||
put ' ';
|
||||
put ' %if NOT %sysevalf(&rV. &rVsign. &pV.) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put ERROR: Package &packageName. will not be loaded!; ';
|
||||
put ' %put ERROR- Required version is &rV0.; ';
|
||||
put ' %put ERROR- Provided version is &pV0.; ';
|
||||
put ' %put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.); ';
|
||||
put ' %put ERROR- Verify installed version of the package.; ';
|
||||
put ' %put ERROR- ; ';
|
||||
put ' %GOTO WrongVersionOFPackage; /*%RETURN;*/ ';
|
||||
put ' %end; ';
|
||||
|
||||
|
||||
put ' filename &_PackageFileref_. &ZIP. ';
|
||||
put ' "&path./%lowcase(&packageName.).&zip." %unquote(&options.) ';
|
||||
@@ -1111,6 +1143,8 @@ data _null_;
|
||||
isProto = 0;
|
||||
isIMLmodule = 0;
|
||||
isCASLudf = 0;
|
||||
isDS2pck = 0;
|
||||
isDS2thr = 0;
|
||||
|
||||
%if (%superq(packageRequired) ne )
|
||||
or (%superq(packageReqPackages) ne )
|
||||
@@ -1350,7 +1384,7 @@ data _null_;
|
||||
('LIBNAME' 'MACRO' /*'MACROS'*/ 'DATA'
|
||||
'FUNCTION' /*'FUNCTIONS'*/ 'FORMAT' /*'FORMATS'*/
|
||||
'IMLMODULE' 'PROTO' 'EXEC' 'CLEAN'
|
||||
'LAZYDATA' 'TEST' 'ADDCNT' 'KMFSNIP'))
|
||||
'LAZYDATA' 'TEST' 'ADDCNT' 'KMFSNIP' 'DS2PCK' 'DS2THR'))
|
||||
then
|
||||
do;
|
||||
putlog 'WARNING: Type ' type 'is not yet supported.';
|
||||
@@ -1361,8 +1395,11 @@ data _null_;
|
||||
isFormat + (upcase(type)=:'FORMAT');
|
||||
isProto + (upcase(type)=:'PROTO');
|
||||
isIMLmodule + (upcase(type)=:'IMLMODULE');
|
||||
isDS2pck + (upcase(type)=:'DS2PCK');
|
||||
isDS2thr + (upcase(type)=:'DS2THR');
|
||||
|
||||
/* HEADERS for IML, FCMP, and PROTO - start */
|
||||
|
||||
/* HEADERS for PROC IML, FCMP, and PROTO - start */
|
||||
if 1 = isFunction and upcase(type)=:'FUNCTION' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used FCMP */
|
||||
@@ -1420,7 +1457,7 @@ data _null_;
|
||||
/* header, for IML modules */
|
||||
put "proc iml ; ";
|
||||
end;
|
||||
/* HEADERS for IML, FCMP, and PROTO - end */
|
||||
/* HEADERS for PROC IML, FCMP, and PROTO - end */
|
||||
|
||||
put ' ' /
|
||||
'%if (%str(*)=%superq(cherryPick)) or (' fileshort +(-1) ' in %superq(cherryPick)) %then %do; '; /* Cherry Pick test1 start */
|
||||
@@ -1431,6 +1468,8 @@ data _null_;
|
||||
put ' %put %sysfunc(ifc(%SYSMACEXIST(' fileshort +(-1) ')=1, NOTE# Macro ' fileshort
|
||||
"exist. It will be overwritten by the macro from the &packageName. package, ));";
|
||||
|
||||
|
||||
/* separate approach for EXEC */
|
||||
if upcase(type)=:'EXEC' then
|
||||
do;
|
||||
/* User can suppress running the exec files */
|
||||
@@ -1453,9 +1492,84 @@ data _null_;
|
||||
/ ' )));'
|
||||
;
|
||||
end;
|
||||
else
|
||||
/* separate approach for DS2 */
|
||||
else if (upcase(type) in: ('DS2PCK' 'DS2THR')) then
|
||||
do;
|
||||
/* include the file with the code of the element */
|
||||
if 1 = isDS2pck and upcase(type)=:'DS2PCK' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used DS2 package */
|
||||
put 'data _null_; ';
|
||||
put " call symputX('cherryPick_DS2PCK', 0, 'L'); ";
|
||||
put 'run; ';
|
||||
end;
|
||||
if 1 = isDS2thr and upcase(type)=:'DS2THR' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used DS2 threads */
|
||||
put 'data _null_; ';
|
||||
put " call symputX('cherryPick_DS2THR', 0, 'L'); ";
|
||||
put 'run; ';
|
||||
end;
|
||||
|
||||
|
||||
/* since DS2 packages and threads are stored in SAS data sets */
|
||||
/* we have to check (before loading) if there is no "regular" */
|
||||
/* data set (or view) with the same name to avoid overwriting */
|
||||
if upcase(type) in: ('DS2PCK' 'DS2THR') then
|
||||
do;
|
||||
length DS2lib $ 8 DS2ds $ 32;
|
||||
DS2lib = coalescec(scan(fileshort,-2,"."), "WORK");
|
||||
DS2ds = scan(fileshort,-1,".");
|
||||
|
||||
put '%put %sysfunc(ifc(%sysfunc(exist(' fileshort +(-1) '))=1,'
|
||||
/ '%sysfunc(dosubl(%str(options ps=min; title; options msglevel=n nodate notes source nomprint;'
|
||||
/ ' data _null_;'
|
||||
/ ' id = OPEN("' fileshort +(-1) '");'
|
||||
/ ' if id then do;'
|
||||
/ ' x = VARNUM(id, "SAS_CHECKSUM_") AND VARNUM(id, "SAS_ROWID_") AND (VARNUM(id, "SAS_TEXTTHREAD_") OR VARNUM(id, "SAS_TEXTPACKAGE_"));'
|
||||
/ ' y = ("DATA"=ATTRC(id, "MTYPE"));'
|
||||
/ ' if symexist("DS2force") then z = symgetn("DS2force"); else z = 0;'
|
||||
/ ' if (x AND y) OR z then do;'
|
||||
/ ' call execute("proc delete data=' fileshort +(-1) '; run;");'
|
||||
/ " put 'NOTE# The " fileshort "will be overwritten by the PROC DS2 package/thread from the &packageName. package.';"
|
||||
|
||||
/* header for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' call execute("proc ds2;");'
|
||||
|
||||
/ ' call execute(''%include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;'');'
|
||||
|
||||
/* footer for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' call execute("run; quit;");'
|
||||
/ ' call execute("options nonotes; proc datasets lib=' DS2lib 'noprint;");'
|
||||
/ " call execute('modify " DS2ds "(label=""Package: &packageName. ; Type: " type "; Name: " fileshort """);');"
|
||||
/ ' call execute("run; quit;");'
|
||||
/ ' end;'
|
||||
/ ' else put "WARNING: Data set ' fileshort 'exist and is not a PROC DS2 package/thread!"'
|
||||
/ ' / "WARNING- PROC DS2 package/thread ' fileshort 'will not be generated..."; '
|
||||
/ ' id = CLOSE(id);'
|
||||
/ ' end;'
|
||||
/ ' run;))),'
|
||||
/ '%sysfunc(dosubl(%str(options ps=min; title; options msglevel=n nodate notes source nomprint;'
|
||||
/* header for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' proc ds2;'
|
||||
|
||||
/ ' %include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;'
|
||||
|
||||
/* footer for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' run; quit;'
|
||||
/ ' options nonotes; proc datasets lib=' DS2lib 'noprint;'
|
||||
/ " modify " DS2ds "(label=""Package: &packageName. ; Type: " type "; Name: " fileshort """);"
|
||||
/ ' run; quit;'
|
||||
/ '))),'
|
||||
/ '));'
|
||||
/ " "
|
||||
/ ;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
else
|
||||
do;
|
||||
/* include the file with the code of the element, all other cases */
|
||||
put ' %include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;';
|
||||
end;
|
||||
|
||||
@@ -1471,13 +1585,19 @@ data _null_;
|
||||
if upcase(type)=:'FORMAT' then
|
||||
put ' %let cherryPick_FORMAT = %eval(&cherryPick_FORMAT. + 1);';
|
||||
|
||||
if upcase(type)=:'DS2PCK' then
|
||||
put ' %let cherryPick_DS2PCK = %eval(&cherryPick_DS2PCK. + 1);';
|
||||
|
||||
if upcase(type)=:'DS2THR' then
|
||||
put ' %let cherryPick_DS2THR = %eval(&cherryPick_DS2THR. + 1);';
|
||||
|
||||
put '%end; ' /; /* Cherry Pick test1 end */
|
||||
|
||||
|
||||
/* FOOTERS for IML, FCMP, and PROTO - start */
|
||||
/* FOOTERS for PROC IML, FCMP, and PROTO - start */
|
||||
if 1 = LAST.type and upcase(type) in ('FUNCTIONS' 'PROTO' 'FORMATS') then
|
||||
do; /* footer, for multiple functions in one FCMP run, one PROTO run, or one FORMAT run */
|
||||
put "run; " / ;
|
||||
put "quit; " / ;
|
||||
end;
|
||||
if 1 = LAST.type and upcase(type)='IMLMODULE' then /* footer, for IML modules */
|
||||
do;
|
||||
@@ -1488,7 +1608,7 @@ data _null_;
|
||||
'%end; ' /
|
||||
"quit; " / ;
|
||||
end;
|
||||
/* FOOTERS for IML, FCMP, and PROTO - end */
|
||||
/* FOOTERS for PROC IML, FCMP, and PROTO - end */
|
||||
|
||||
/* add the link to the functions dataset, only for the first occurrence */
|
||||
/*if 1 = isFunction and (upcase(type)=:'FUNCTION') then
|
||||
@@ -1576,7 +1696,7 @@ data _null_;
|
||||
%end;
|
||||
put +(-1) '`.;''' /
|
||||
' !! '' %put The macro generated: '' !! put(dtCASLudf, E8601DT19.-L) !! ";"' /
|
||||
' !! '' %put with the SAS Packages Framework version 20240927.;''' /
|
||||
' !! '' %put with the SAS Packages Framework version 20241207.;''' /
|
||||
' !! '' %put ****************************************************************************;''' /
|
||||
' !! '' %GOTO theEndOfTheMacro;''' /
|
||||
' !! '' %end;''' ;
|
||||
@@ -1741,7 +1861,7 @@ data _null_;
|
||||
%end;
|
||||
put +(-1) '`.; '' !!' /
|
||||
''' %put The macro generated: ''' " !! put(dtIML, E8601DT19.-L) !! " '''; '' !!' /
|
||||
''' %put with the SAS Packages Framework version 20240927.; '' !! ' /
|
||||
''' %put with the SAS Packages Framework version 20241207.; '' !! ' /
|
||||
''' %put ****************************************************************************; '' !! ' /
|
||||
''' %GOTO theEndOfTheMacro; '' !! ' /
|
||||
''' %end; '' !! ' /
|
||||
@@ -2256,15 +2376,33 @@ data _null_;
|
||||
/* put 'remove module = ' fileshort ';'; */
|
||||
end;
|
||||
|
||||
/* delete datasets */
|
||||
put "proc sql noprint;";
|
||||
/* delete data sets */
|
||||
put "proc SQL noprint;";
|
||||
EOF = 0;
|
||||
do until(EOF);
|
||||
set &filesWithCodes. end = EOF;
|
||||
if not (upcase(type)=:'DATA') then continue;
|
||||
if not (upcase(type) in: ('DATA')) then continue;
|
||||
put '%put NOTE- Element of type ' type 'generated from the file "' file +(-1) '" will be deleted;';
|
||||
put '%put NOTE- ;';
|
||||
put 'drop table ' fileshort ';' /;
|
||||
put '%sysfunc(ifc(%sysfunc(exist(' fileshort ')),drop table ' fileshort ',));' /;
|
||||
end;
|
||||
put "quit;" /;
|
||||
|
||||
/* delete PROC DS2 packages or threads */
|
||||
put 'data _null_; call symputx("_DS2_2_del_",0,"L"); run;';
|
||||
put "proc SQL noprint;";
|
||||
EOF = 0;
|
||||
do until(EOF);
|
||||
set &filesWithCodes. end = EOF;
|
||||
if not (upcase(type) in: ('DS2PCK' 'DS2THR')) then continue;
|
||||
put '%put NOTE- Element of type ' type 'generated from the file "' file +(-1) '" will be deleted;'
|
||||
/ '%put NOTE- ;'
|
||||
/ '%let _DS2_2_del_ = %sysfunc(open(' fileshort '));'
|
||||
/ '%sysfunc(ifc(&_DS2_2_del_. AND %sysfunc(ATTRC(&_DS2_2_del_.,LABEL))='
|
||||
/ '%str(' "Package: &packageName. ; Type: " type "; Name: " fileshort +(-1) '),drop table ' fileshort ',)) '
|
||||
/ '%let _DS2_2_del_ = %sysfunc(close(&_DS2_2_del_.));'
|
||||
;
|
||||
put ';' /; /* this is semicolon closing drop table statement */
|
||||
end;
|
||||
put "quit;" /;
|
||||
|
||||
@@ -2392,12 +2530,13 @@ data _null_;
|
||||
|
||||
length fileshort2 $ 256;
|
||||
select;
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'");
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'" );
|
||||
when (upcase(type) =: "FUNCTION" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "IMLMODULE" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "PROTO" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "FORMAT" ) fileshort2 = cats("'$", fileshort, ".'" );
|
||||
when (upcase(type) in ('DS2PCK' 'DS2THR')) fileshort2 = cats("'DS2", fileshort, "'" );
|
||||
otherwise fileshort2 = fileshort;
|
||||
end;
|
||||
strX = catx('/', folder, order, type, file, fileshort, fileshort2);
|
||||
@@ -2529,7 +2668,7 @@ data _null_;
|
||||
%end;
|
||||
|
||||
put 'put " " / @3 "--------------------------------------------------------------------" / " ";'
|
||||
/ 'put @3 "*SAS package generated by SAS Package Framework, version `20240927`*";'
|
||||
/ 'put @3 "*SAS package generated by SAS Package Framework, version `20241207`*";'
|
||||
/ 'put " " / @3 "--------------------------------------------------------------------";';
|
||||
|
||||
put 'run; ' /;
|
||||
@@ -2568,13 +2707,14 @@ data _null_;
|
||||
|
||||
length fileshort2 $ 256;
|
||||
select;
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'");
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'" );
|
||||
when (upcase(type) =: "FUNCTION" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "IMLMODULE" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "PROTO" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "FORMAT" ) fileshort2 = cats("'$", fileshort, ".'" );
|
||||
when (upcase(type) =: "CASLUDF" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) in ('DS2PCK' 'DS2THR')) fileshort2 = cats("'DS2", fileshort, "'" );
|
||||
otherwise fileshort2 = fileshort;
|
||||
end;
|
||||
strX = catx('/', folder, order, type, file, fileshort, fileshort2);
|
||||
@@ -3057,7 +3197,7 @@ run;
|
||||
|
||||
%if %Qupcase(&sascfgFile.) = DEF %then /* the DEF value points to the sasv9.cfg file in the sasroot directory */
|
||||
%do;
|
||||
%let SASCONFIG = -config ""&SASROOT./sasv9.cfg"";
|
||||
%let SASCONFIG = -config "&SASROOT./sasv9.cfg";
|
||||
%put NOTE: The following SAS config file will be used:;
|
||||
%put NOTE- &=SASCONFIG.;
|
||||
%end;
|
||||
@@ -3065,7 +3205,7 @@ run;
|
||||
%do;
|
||||
%if %sysfunc(fileexist(&sascfgFile.)) %then
|
||||
%do;
|
||||
%let SASCONFIG = -config ""&SASCFGFILE."";
|
||||
%let SASCONFIG = -config "&SASCFGFILE.";
|
||||
%put NOTE: The following SAS config file will be used:;
|
||||
%put NOTE- &=SASCONFIG.;
|
||||
%end;
|
||||
@@ -3566,7 +3706,7 @@ data &filesWithCodes.markdown;
|
||||
%end;
|
||||
|
||||
put " " / "--------------------------------------------------------------------" / " "
|
||||
/ "*SAS package generated by SAS Package Framework, version `20240927`*"
|
||||
/ "*SAS package generated by SAS Package Framework, version `20241207`*"
|
||||
/ " " / "--------------------------------------------------------------------" / " ";
|
||||
|
||||
put "# The `&packageName.` package content";
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to get help about SAS package, version 20240927. Run %helpPackage() for help info.'
|
||||
des = 'Macro to get help about SAS package, version 20241207. Run %helpPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -43,7 +43,7 @@ des = 'Macro to get help about SAS package, version 20240927. Run %helpPackage()
|
||||
%put ### This is short help information for the `helpPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to get help about SAS packages, version `20240927` #;
|
||||
%put # Macro to get help about SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*+installPackage+*/
|
||||
/* Macros to install SAS packages, version 20240927 */
|
||||
/* Macros to install SAS packages, version 20241207 */
|
||||
/* A SAS package is a zip file containing a group of files
|
||||
with SAS code (macros, functions, data steps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
@@ -18,12 +18,14 @@
|
||||
, URLoptions = /* options for the `sourcePath` URLs */
|
||||
, loadAddCnt=0 /* should the additional content be loaded?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, instDoc=0 /* should the markdown file with documentation be installed?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, SFRCVN = /* name of a macro variable to store success-failure return code value */
|
||||
)
|
||||
/secure
|
||||
minoperator
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to install SAS package, version 20240927. Run %%installPackage() for help info.'
|
||||
des = 'Macro to install SAS package, version 20241207. Run %%installPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
|
||||
%do;
|
||||
@@ -38,7 +40,7 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%put ### This is short help information for the `installPackage` macro #;
|
||||
%put #--------------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to install SAS packages, version `20240927` #;
|
||||
%put # Macro to install SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -102,6 +104,11 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%put # directory in `<packageName>_AdditionalContent` folder. #;
|
||||
%put # For other locations use `%nrstr(%%loadPackageAddCnt())` macro. #;
|
||||
%put # #;
|
||||
%put # - `instDoc=` *Optional.* A package may be provided with a markdown file #;
|
||||
%put # containing combined documentation of the package. The option #;
|
||||
%put # indicates if the `.md` file should be also downloaded. #;
|
||||
%put # Default value of zero (`0`) means "No", one (`1`) means "Yes". #;
|
||||
%put # #;
|
||||
%put # - `SFRCVN=` *Optional.* Provides a NAME for a macro variable to store value of the #;
|
||||
%put # *success-failure return code* of the installation process. Return value #;
|
||||
%put # has the following form: `<number of successes>.<number of failures>` #;
|
||||
@@ -182,30 +189,39 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
call symputX("firstPackagesPath", pathname("packages"), "L");
|
||||
run;
|
||||
|
||||
%let loadAddCnt = %sysevalf(NOT(0=%superq(loadAddCnt)));
|
||||
%let instDoc = %sysevalf(NOT(0=%superq(instDoc)));
|
||||
|
||||
%let replace = %sysevalf(1=%superq(replace));
|
||||
|
||||
%if %superq(sourcePath)= %then
|
||||
%do;
|
||||
%local SPFinitMirror;
|
||||
%local SPFinitMirror SPFinitMirrorMD;
|
||||
/* the defaults are: */
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/packages/;
|
||||
|
||||
%if 0 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://github.com/SASPAC/; /*usercontent*/
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
|
||||
%if 1 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/packages/;
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
|
||||
%if 2 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.md;
|
||||
%let sourcePath = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/packages/;
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
@@ -215,7 +231,8 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%else
|
||||
%do;
|
||||
%let mirror=-1;
|
||||
%let SPFinitMirror = &sourcePath.SPFinit.sas;
|
||||
%let SPFinitMirror = &sourcePath.SPFinit.sas;
|
||||
%let SPFinitMirrorMD = &sourcePath.SPFinit.md;
|
||||
%end;
|
||||
|
||||
%local i str;
|
||||
@@ -262,10 +279,13 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%put ### &packageName.(&vers.) ###;
|
||||
|
||||
%put *** %lowcase(&packageName.) start *****************************************;
|
||||
%local in out _IOFileref_;
|
||||
%local in out inMD outMD _IOFileref_;
|
||||
data _null_; call symputX("_IOFileref_", put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
|
||||
%let in = i&_IOFileref_.;
|
||||
%let out = o&_IOFileref_.;
|
||||
%let inMD = j&_IOFileref_.;
|
||||
%let outMD = u&_IOFileref_.;
|
||||
|
||||
/* %let in = i%sysfunc(md5(&packageName.),hex7.); */
|
||||
/* %let out = o%sysfunc(md5(&packageName.),hex7.); */
|
||||
|
||||
@@ -275,17 +295,27 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
/* allows to install/download the framework file like any other package */
|
||||
%if %superq(mirror) in (0 1) AND (%superq(vers) ne) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.md;
|
||||
%end;
|
||||
%if %superq(mirror) > 1 %then
|
||||
%put %str( )Mirror %superq(mirror) does not support versioning.;
|
||||
|
||||
filename &in URL
|
||||
/* source code file */
|
||||
filename &in. URL
|
||||
"&SPFinitMirror."
|
||||
recfm=N lrecl=1;
|
||||
filename &out
|
||||
filename &out.
|
||||
"&firstPackagesPath./SPFinit.sas"
|
||||
recfm=N lrecl=1;
|
||||
|
||||
/* documentation MD file */
|
||||
filename &inMD. URL
|
||||
"&SPFinitMirrorMD."
|
||||
recfm=N lrecl=1;
|
||||
filename &outMD.
|
||||
"&firstPackagesPath./SPFinit.md"
|
||||
recfm=N lrecl=1;
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
@@ -305,7 +335,8 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%put %str( )Mirror %superq(mirror) does not support versioning.;
|
||||
%end;
|
||||
|
||||
filename &in URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).zip"
|
||||
/* zip */
|
||||
filename &in. URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).zip"
|
||||
%if (%superq(URLuser) ne ) %then
|
||||
%do;
|
||||
user = "&URLuser."
|
||||
@@ -313,7 +344,17 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%end;
|
||||
&URLoptions.
|
||||
recfm=N lrecl=1;
|
||||
filename &out "&firstPackagesPath./%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
filename &out. "&firstPackagesPath./%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
/* markdown */
|
||||
filename &inMD. URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).md"
|
||||
%if (%superq(URLuser) ne ) %then
|
||||
%do;
|
||||
user = "&URLuser."
|
||||
pass = "&URLuser."
|
||||
%end;
|
||||
&URLoptions.
|
||||
recfm=N lrecl=1;
|
||||
filename &outMD. "&firstPackagesPath./%lowcase(&packageName.).md" recfm=N lrecl=1;
|
||||
%end;
|
||||
/*
|
||||
filename in list;
|
||||
@@ -323,12 +364,21 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
%local installationRC;
|
||||
%let installationRC=1;
|
||||
data _null_;
|
||||
length filein 8 out_path in_path $ 4096;
|
||||
length filein fileinMD 8
|
||||
out_path in_path out_pathMD in_pathMD rcTXT $ 4096
|
||||
out_ref in_ref out_refMD in_refMD $ 8
|
||||
;
|
||||
out_path = pathname ("&out");
|
||||
in_path = pathname ("&in" );
|
||||
out_pathMD = pathname ("&outMD");
|
||||
in_pathMD = pathname ("&inMD" );
|
||||
out_ref = symget ("out");
|
||||
in_ref = symget ("in" );
|
||||
out_refMD = symget ("outMD");
|
||||
in_refMD = symget ("inMD" );
|
||||
rcTXT=' ';
|
||||
|
||||
|
||||
filein = fopen( "&in", 'S', 1, 'B');
|
||||
filein = fopen(in_ref, 'S', 1, 'B');
|
||||
if filein = 0 then
|
||||
put "ERROR: Source file:" /
|
||||
"ERROR- " in_path /
|
||||
@@ -348,21 +398,23 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
rc = FCLOSE(filein);
|
||||
put;
|
||||
|
||||
if FEXIST("&out") = 0 then
|
||||
if FEXIST(out_ref) = 0 then
|
||||
do;
|
||||
put @2 "Installing the &packageName. package"
|
||||
/ @2 "in the &firstPackagesPath. directory.";
|
||||
rc = FCOPY("&in", "&out");
|
||||
rc = FCOPY(in_ref, out_ref);
|
||||
rcTXT=sysmsg();
|
||||
end;
|
||||
else if FEXIST("&out") = 1 then
|
||||
else if FEXIST(out_ref) = 1 then
|
||||
do;
|
||||
if symgetn("replace")=1 then
|
||||
do;
|
||||
put @2 "The following file will be replaced during "
|
||||
/ @2 "installation of the &packageName. package: "
|
||||
/ @5 out_path;
|
||||
rc = FDELETE("&out");
|
||||
rc = FCOPY("&in", "&out");
|
||||
rc = FDELETE(out_ref);
|
||||
rc = FCOPY(in_ref, out_ref);
|
||||
rcTXT=sysmsg();
|
||||
end;
|
||||
else
|
||||
do;
|
||||
@@ -371,13 +423,41 @@ des = 'Macro to install SAS package, version 20240927. Run %%installPackage() fo
|
||||
rc = 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
put @2 "Done with return code " rc= "(zero = success)";
|
||||
put @2 "Done with return code " rc= "(zero = success)" / rcTXT;
|
||||
call symputX("installationRC", rc, "L");
|
||||
|
||||
/* try to install documentation file */
|
||||
if 1=symgetn("instDoc") then
|
||||
do;
|
||||
fileinMD = fopen(in_refMD, 'S', 1, 'B');
|
||||
rcMD = FCLOSE(fileinMD);
|
||||
|
||||
if fileinMD then
|
||||
do;
|
||||
if 0=FEXIST(out_refMD) then
|
||||
do;
|
||||
rcMD = FCOPY(in_refMD, out_refMD);
|
||||
if rcMD=0 then
|
||||
put @2 "Package documentation installed on request." ; /* / out_pathMD / in_pathMD; */
|
||||
end;
|
||||
else if 1=FEXIST(out_refMD) and 1=symgetn("replace") then
|
||||
do;
|
||||
rcMD = FDELETE(out_refMD);
|
||||
if rcMD=0 then
|
||||
rcMD2 = FCOPY(in_refMD, out_refMD);
|
||||
if rcMD=0 AND rcMD2=0 then
|
||||
put @2 "Package documentation installed on demand." ; /* / out_pathMD / in_pathMD; */
|
||||
end;
|
||||
end;
|
||||
else
|
||||
put @2 "Package documentation in markdown format not available." ; /* / out_pathMD / in_pathMD;*/
|
||||
end;
|
||||
run;
|
||||
|
||||
filename &in clear;
|
||||
filename &out clear;
|
||||
filename &in. clear;
|
||||
filename &out. clear;
|
||||
filename &inMD. clear;
|
||||
filename &outMD. clear;
|
||||
|
||||
%if 0 = &installationRC. %then
|
||||
%do;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Macro to list SAS packages in packages folder.
|
||||
|
||||
Version 20240927
|
||||
Version 20241207
|
||||
|
||||
A SAS package is a zip file containing a group
|
||||
of SAS codes (macros, functions, data steps generating
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
%macro listPackages()
|
||||
/secure PARMBUFF
|
||||
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20240927.'
|
||||
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20241207.'
|
||||
;
|
||||
%if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then
|
||||
%do;
|
||||
@@ -38,7 +38,7 @@ des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HE
|
||||
%put ### This is short help information for the `listPackages` macro #;
|
||||
%put #-----------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to list available SAS packages, version `20240927` #;
|
||||
%put # Macro to list available SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
@@ -30,11 +30,13 @@
|
||||
, loadAddCnt=0 /* should the additional content be loaded?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, suppressExec=0 /* indicates if loading of exec files
|
||||
should be suppressed, 1=suppress
|
||||
should be suppressed, 1=suppress */
|
||||
, DS2force=0 /* indicates if PROC DS2 packages and threads
|
||||
should be loaded if a data set exists, 0=do not load
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load SAS package, version 20240927. Run %loadPackage() for help info.'
|
||||
des = 'Macro to load SAS package, version 20241207. Run %loadPackage() for help info.'
|
||||
minoperator
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
@@ -50,7 +52,7 @@ minoperator
|
||||
%put ### This is short help information for the `loadPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to *load* SAS packages, version `20240927` #;
|
||||
%put # Macro to *load* SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -110,6 +112,10 @@ minoperator
|
||||
%put # should be suppressed, default value is `0`, #;
|
||||
%put # when set to `1` `exec` files are *not* loaded #;
|
||||
%put # #;
|
||||
%put # - `DS2force=` *Optional.* Indicates if loading of `PROC DS2` packages #;
|
||||
%put # or threads should overwrite existing SAS data sets. #;
|
||||
%put # Default value of `0` means "do not overwrite". #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
|
||||
@@ -212,6 +218,11 @@ minoperator
|
||||
%let suppressExec = 0;
|
||||
%end;
|
||||
|
||||
%if %superq(DS2force) NE 1 %then
|
||||
%do;
|
||||
%let DS2force = 0;
|
||||
%end;
|
||||
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
/* put location of package myPackageFile.zip here */
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
@@ -222,21 +233,31 @@ minoperator
|
||||
filename &_PackageFileref_. clear;
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
%local rV pV;
|
||||
%let pV = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV.,3,.,M)+0)*1e0);
|
||||
%let rV = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV.,3,.,M)+0)*1e0);
|
||||
%local rV pV rV0 pV0 rVsign;
|
||||
%let pV0 = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%let rV0 = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k));
|
||||
%if %superq(rVsign)= %then %let rVsign=<=;
|
||||
%else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then
|
||||
%do;
|
||||
%put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.;
|
||||
%put WARNING- Supported operators are: %str(= <= =< => >= < >);
|
||||
%let rVsign=<=;
|
||||
%end;
|
||||
%let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%if %sysevalf(&rV. > &pV.) %then
|
||||
%if NOT %sysevalf(&rV. &rVsign. &pV.) %then
|
||||
%do;
|
||||
%put ERROR: Package &packageName. will not be loaded!;
|
||||
%put ERROR- Required version is &requiredVersion.;
|
||||
%put ERROR- Provided version is &packageVersion.;
|
||||
%put ERROR- Required version is &rV0.;
|
||||
%put ERROR- Provided version is &pV0.;
|
||||
%put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.);
|
||||
%put ERROR- Verify installed version of the package.;
|
||||
%put ERROR- ;
|
||||
%GOTO WrongVersionOFPackage; /*%RETURN;*/
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
is provided in required version */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load additional content for a SAS package, version 20240927. Run %loadPackageAddCnt() for help info.'
|
||||
des = 'Macro to load additional content for a SAS package, version 20241207. Run %loadPackageAddCnt() for help info.'
|
||||
minoperator
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
@@ -35,7 +35,7 @@ minoperator
|
||||
%put ### This is short help information for the `loadPackageAddCnt` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to *load* additional content for a SAS package, version `20240927` #;
|
||||
%put # Macro to *load* additional content for a SAS package, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -157,22 +157,33 @@ minoperator
|
||||
%include &_PackageFileref_.(packagemetadata.sas) / &source2.;
|
||||
filename &_PackageFileref_. clear;
|
||||
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
%local rV pV;
|
||||
%let pV = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV.,3,.,M)+0)*1e0);
|
||||
%let rV = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV.,3,.,M)+0)*1e0);
|
||||
%local rV pV rV0 pV0 rVsign;
|
||||
%let pV0 = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%let rV0 = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k));
|
||||
%if %superq(rVsign)= %then %let rVsign=<=;
|
||||
%else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then
|
||||
%do;
|
||||
%put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.;
|
||||
%put WARNING- Supported operators are: %str(= <= =< => >= < >);
|
||||
%let rVsign=<=;
|
||||
%end;
|
||||
%let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%if %sysevalf(&rV. > &pV.) %then
|
||||
%if NOT %sysevalf(&rV. &rVsign. &pV.) %then
|
||||
%do;
|
||||
%put ERROR: Additional content for package &packageName. will not be loaded!;
|
||||
%put ERROR- Required version is &requiredVersion.;
|
||||
%put ERROR- Provided version is &packageVersion.;
|
||||
%put ERROR- Required version is &rV0.;
|
||||
%put ERROR- Provided version is &pV0.;
|
||||
%put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.);
|
||||
%put ERROR- Verify installed version of the package.;
|
||||
%put ERROR- ;
|
||||
%GOTO WrongVersionOFPackageAddCnt; /*%RETURN;*/
|
||||
@@ -370,7 +381,5 @@ minoperator
|
||||
%ENDofloadPackageAddCnt:
|
||||
%mend loadPackageAddCnt;
|
||||
|
||||
|
||||
|
||||
|
||||
/**/
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load multiple SAS packages at one run, version 20240927. Run %loadPackages() for help info.'
|
||||
des = 'Macro to load multiple SAS packages at one run, version 20241207. Run %loadPackages() for help info.'
|
||||
parmbuff
|
||||
;
|
||||
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
|
||||
@@ -27,7 +27,7 @@ parmbuff
|
||||
%put ### This is short help information for the `loadPackageS` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro wrapper for the loadPackage macro, version `20240927` #;
|
||||
%put # Macro wrapper for the loadPackage macro, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -79,7 +79,7 @@ parmbuff
|
||||
%local lengthOfsyspbuff numberOfPackagesNames i packageElement packageName packageVersion str;
|
||||
|
||||
%let lengthOfsyspbuff = %qsysfunc(length(&syspbuff.));
|
||||
%let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), {[(. _,)]}, KDA));
|
||||
%let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), {[(. <=>_,)]}, KDA));
|
||||
|
||||
%let str = %qsysfunc(translate(%superq(packagesNames),[[ ]],{(,)}));
|
||||
%let str = %qsysfunc(transtrn(%superq(str),],%str(] )));
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to preview content of a SAS package, version 20240927. Run %previewPackage() for help info.'
|
||||
des = 'Macro to preview content of a SAS package, version 20241207. Run %previewPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -38,7 +38,7 @@ des = 'Macro to preview content of a SAS package, version 20240927. Run %preview
|
||||
%put ### This is short help information for the `previewPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to get preview of a SAS packages, version `20240927` #;
|
||||
%put # Macro to get preview of a SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
422
SPF/Macros/splitcodeforpackage.sas
Normal file
422
SPF/Macros/splitcodeforpackage.sas
Normal file
@@ -0,0 +1,422 @@
|
||||
/*+splitCodeForPackage+*/
|
||||
/*** HELP START ***/
|
||||
|
||||
%macro splitCodeForPackage(
|
||||
codeFile /* a code file to split */
|
||||
,packagePath= /* location for results */
|
||||
,debug=0 /* technical parameter */
|
||||
,nobs=0 /* technical parameter */
|
||||
)
|
||||
/*** HELP START ***/
|
||||
/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20241207. Run %splitCodeForPackage() for help info.'
|
||||
;
|
||||
/*%macro _();%mend _;*/
|
||||
%if (%superq(codeFile) = ) OR (%qupcase(&codeFile.) = HELP) %then
|
||||
%do;
|
||||
%local options_tmp ;
|
||||
%let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps))
|
||||
%sysfunc(getoption(notes)) %sysfunc(getoption(source))
|
||||
msglevel=%sysfunc(getoption(msglevel))
|
||||
;
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
%put ;
|
||||
%put #################################################################################;
|
||||
%put ### This is short help information for the `splitCodeForPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Utility macro to *split* single file with SAS package code into multiple #;
|
||||
%put # files with separate snippets, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single `load.sas` file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # The `%nrstr(%%splitCodeForPackage())` macro takes a file with SAS code #;
|
||||
%put # snippets surrounded by `%str(/)*##$##-code-block-start-##$## <tag spec> *%str(/)` and #;
|
||||
%put # `%str(/)*##$##-code-block-end-##$## <tag spec> *%str(/)` tags and split that file into #;
|
||||
%put # multiple files and directories according to a tag specification. #;
|
||||
%put # #;
|
||||
%put # The `<tag spec>` is a list of pairs of the form: `type(object)` that #;
|
||||
%put # indicates how the file should be split. See example 1 below for details. #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put #### Parameters: #;
|
||||
%put # #;
|
||||
%put # 1. `codeFile=` *Required.* Name of a file containing code #;
|
||||
%put # that will be split. Required and not null. #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # - `packagePath=` *Required.* Location for package files after #;
|
||||
%put # splitting into separate files and directories. #;
|
||||
%put # If missing or not exist then `WORK` is uded. #;
|
||||
%put # #;
|
||||
%put # - `debug=` *Optional.* Turns on code printing for debugging. #;
|
||||
%put # #;
|
||||
%put # - `nobs=` *Optional.* Technical parameter with value `0`. #;
|
||||
%put # Do not change. #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
|
||||
%put # to learn more. #;
|
||||
%put # #;
|
||||
%put ### Example 1 ###################################################################;
|
||||
%put # #;
|
||||
%put # Assume that the `myPackageCode.sas` file #;
|
||||
%put # is located in the `C:/lazy/` folder and #;
|
||||
%put # contain the following code and tags: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put ;
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 01_macro(abc) */ );
|
||||
%put %nrstr( %%macro abc(); );
|
||||
%put %nrstr( %%put I am "abc".; );
|
||||
%put %nrstr( %%mend abc; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 01_macro(abc) */ );
|
||||
%put ;
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 01_macro(efg) */ );
|
||||
%put %nrstr( %%macro efg(); );
|
||||
%put %nrstr( %%put I am "efg".; );
|
||||
%put %nrstr( %%mend efg; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 01_macro(efg) */ );
|
||||
%put ;
|
||||
%put %nrstr( proc FCMP outlib=work.f.p; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 02_functions(xyz) */ );
|
||||
%put %nrstr( function xyz(n); );
|
||||
%put %nrstr( return(n**2 + n + 1) );
|
||||
%put %nrstr( endfunc; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 02_functions(xyz) */ );
|
||||
%put %nrstr( quit; );
|
||||
%put ;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
%put # #;
|
||||
%put # and we want results in `C:/split/` folder, we run the following: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put %nrstr( filename packages "C:/SAS_PACKAGES"; %%* setup a directory for packages;);
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put ;
|
||||
%put %nrstr( %%splitCodeForPackage%( );
|
||||
%put %nrstr( codeFile=C:/lazy/myPackageCode.sas );
|
||||
%put %nrstr( ,packagePath=C:/split/ %) );
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
%put # #;
|
||||
%put #################################################################################;
|
||||
%put ;
|
||||
options &options_tmp.;
|
||||
%GOTO ENDofsplitCodeForPackage;
|
||||
%end;
|
||||
|
||||
|
||||
%local options_tmp2 ;
|
||||
%let options_tmp2 = ls=%sysfunc(getoption(ls)) ps=%sysfunc(getoption(ps))
|
||||
%sysfunc(getoption(notes)) %sysfunc(getoption(source))
|
||||
msglevel=%sysfunc(getoption(msglevel))
|
||||
;
|
||||
options nomprint nosymbolgen nomlogic notes source ls=MAX ps=MAX msglevel=N ;
|
||||
|
||||
%let debug = %sysevalf(NOT(0=%superq(debug)));
|
||||
%if 1=&debug. %then
|
||||
%do;
|
||||
options mprint symbolgen mlogic source source2 msglevel=i;
|
||||
%end;
|
||||
|
||||
%put NOTE- --&SYSMACRONAME.-START--;
|
||||
%local rc;
|
||||
%let rc = %sysfunc(doSubL(%nrstr(
|
||||
options
|
||||
%sysfunc(ifc(1=&debug.
|
||||
,msglevel=I ls=max ps=64 notes mprint symbolgen mlogic source source2
|
||||
,msglevel=N ls=max ps=64 nonotes nomprint nosymbolgen nomlogic nosource nosource2
|
||||
))
|
||||
;;;;
|
||||
|
||||
options DLcreateDir;
|
||||
libname w "%sysfunc(pathname(WORK))/_splitCodeForPackage_";
|
||||
filename d "%sysfunc(pathname(WORK))/_splitCodeForPackage_/dummy";
|
||||
data _null_;
|
||||
file d;
|
||||
put "dummy";
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
length codeFile $ 4096;
|
||||
codeFile = symget('codeFile');
|
||||
codeFile = dequote(codeFile);
|
||||
|
||||
if fileexist(codeFile) then
|
||||
do;
|
||||
codeFile = quote(strip(codeFile),"'");
|
||||
call symputX("codeFile",codeFile,"L");
|
||||
end;
|
||||
else
|
||||
do;
|
||||
put "ERROR: [splitCodeForPackage] File " codeFile 'does not exist!';
|
||||
call symputX("codeFile",quote(strip(pathname('d'))),"L");
|
||||
end;
|
||||
run;
|
||||
|
||||
options notes;
|
||||
filename source &codeFile.;
|
||||
filename source LIST;
|
||||
options nonotes;
|
||||
|
||||
data _null_;
|
||||
length packagePath work $ 4096;
|
||||
work = pathname('WORK');
|
||||
packagePath = coalescec(symget('packagePath'), work);
|
||||
rc = fileexist(packagePath);
|
||||
if NOT rc then packagePath = work;
|
||||
if rc = 1 then put "INFO: " @;
|
||||
else put "WARNING: " @;
|
||||
put packagePath=;
|
||||
call symputX('packagePath',packagePath,"L");
|
||||
run;
|
||||
|
||||
|
||||
data w.files;
|
||||
stop;
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
if 1 = _N_ then
|
||||
do;
|
||||
declare hash H(ordered:"A");
|
||||
H.defineKey('token');
|
||||
H.defineData('token','start','end','lineNumber');
|
||||
H.defineDone();
|
||||
end;
|
||||
if 1 = _E_ then
|
||||
do;
|
||||
H.output(dataset:'w.files');
|
||||
end;
|
||||
|
||||
infile source END=_E_;
|
||||
lineNumberN+1;
|
||||
input;
|
||||
|
||||
length line $ 4096 lineNumber $ 256;
|
||||
line = left(lowcase(_infile_));
|
||||
block=scan(line,1," ");
|
||||
|
||||
if block in (
|
||||
'/*##$##-code-block-start-##$##'
|
||||
'/*##$##-code-block-end-##$##'
|
||||
);
|
||||
|
||||
if substr(block,20,1) = 's' then
|
||||
do; s=1; e=0; end;
|
||||
else
|
||||
do; s=0; e=1; end;
|
||||
|
||||
i=1;
|
||||
token=block;
|
||||
do while(i);
|
||||
i+1;
|
||||
token=scan(line,i," ");
|
||||
if token='*/' OR token=' ' then i=0;
|
||||
else
|
||||
do;
|
||||
start=0; end=0;
|
||||
if H.find() then
|
||||
do;
|
||||
start=s;
|
||||
end =e;
|
||||
lineNumber = cats(lineNumberN);
|
||||
end;
|
||||
else
|
||||
do;
|
||||
start+s;
|
||||
end +e;
|
||||
lineNumber = catx(",",lineNumber,lineNumberN);
|
||||
end;
|
||||
H.replace();
|
||||
/*putlog token= s= e= start= end=;*/
|
||||
end;
|
||||
end;
|
||||
run;
|
||||
|
||||
title;
|
||||
title1 "Attention!!! Not Matching Tags!";
|
||||
title2 "Verify following tags in file:";
|
||||
title3 &codeFile.;
|
||||
proc print data=w.files(where=(start NE end));
|
||||
run;
|
||||
title;
|
||||
|
||||
data w.files;
|
||||
set w.files end=_E_ nobs=nobs;
|
||||
where start=end;
|
||||
length dir $ 128 code $ 32 path $ 160;
|
||||
dir =coalescec(scan(token,1,'()'),'!BAD_DIRECTORY');
|
||||
code=coalescec(scan(token,2,'()'),'!BAD_CODE_FILE');
|
||||
if dir = '!BAD_DIRECTORY' or code = '!BAD_CODE_FILE' then
|
||||
put "WARNING: Bad directory or code file name!"
|
||||
/ "WARNING- Check tag: " token ;
|
||||
path=cats('/',dir,'/',code,'.sas'); /* .sas */
|
||||
run;
|
||||
|
||||
title;
|
||||
title1 "List of tags with value _ALL_ for 'dir' or 'code' variable.";
|
||||
title2 "Snippets tagged this way will be copied to multiple files.";
|
||||
proc print data=w.files(where=(dir = '_all_' OR code = '_all_'));
|
||||
run;
|
||||
title;
|
||||
|
||||
data w.files;
|
||||
if 0=nobs then
|
||||
put "WARNING: No tags found in the file";
|
||||
|
||||
set w.files end=_E_ nobs=nobs;
|
||||
where dir NE '_all_' AND code NE '_all_';
|
||||
n+1;
|
||||
if 1 = _E_ then
|
||||
call symputX('nobs',n,"L");
|
||||
run;
|
||||
|
||||
title;
|
||||
title "List of files";
|
||||
proc print data=w.files;
|
||||
run;
|
||||
title;
|
||||
|
||||
data _null_;
|
||||
set w.files;
|
||||
rc = libname("_",catx("/",symget('packagePath'),dir));
|
||||
rc = libname("_");
|
||||
run;
|
||||
|
||||
filename f DUMMY;
|
||||
data _null_;
|
||||
if 1 =_N_ then
|
||||
do;
|
||||
array paths[0:&nobs.] $ 128 _temporary_;
|
||||
array starts[0:&nobs.] _temporary_;
|
||||
array ends[0:&nobs.] _temporary_;
|
||||
array write[0:&nobs.] _temporary_;
|
||||
array firstLine[0:&nobs.] _temporary_;
|
||||
|
||||
declare hash H();
|
||||
H.defineKey('token');
|
||||
H.defineData('n');
|
||||
H.defineDone();
|
||||
|
||||
do until(_E_);
|
||||
set w.files end=_E_;
|
||||
paths[n]=path;
|
||||
starts[n]=start;
|
||||
ends[n]=end;
|
||||
write[n]=0;
|
||||
rc=H.add();
|
||||
firstLine[n]=1;
|
||||
end;
|
||||
_E_=.;
|
||||
length packagePath $ 4096;
|
||||
retain packagePath " ";
|
||||
packagePath=symget('packagePath');
|
||||
end;
|
||||
|
||||
infile source END=_E_;
|
||||
input;
|
||||
|
||||
length line /*lineToPrint*/ $ 4096;
|
||||
line = left(lowcase(_infile_));
|
||||
/*lineToPrint=_infile_;*/
|
||||
block=scan(line,1," ");
|
||||
|
||||
if block in (
|
||||
'/*##$##-code-block-start-##$##'
|
||||
'/*##$##-code-block-end-##$##'
|
||||
) then
|
||||
do;
|
||||
/********************************************************/
|
||||
if substr(block,20,1) = 's' then
|
||||
do; s=1; e=0; end;
|
||||
else
|
||||
do; s=0; e=1; end;
|
||||
|
||||
i=1;
|
||||
token=block;
|
||||
do while(i);
|
||||
i+1;
|
||||
token=scan(line,i," ");
|
||||
if token='*/' OR token=' ' then i=0; /* if it is the end of list - stop */
|
||||
else if token='_all_(_all_)' then /* if this is a snippet for ALL files in a package */
|
||||
do k=1 to &nobs.;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
else if scan(token,2,'()')='_all_' then /* if this is a snippet for ALL files in a type */
|
||||
do k=1 to &nobs.;
|
||||
if scan(token,1,'()')=scan(paths[k],1,'/\') then
|
||||
do;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
end;
|
||||
else if scan(token,1,'()')='_all_' then /* if this is a snippet for ALL files with the same name */
|
||||
do k=1 to &nobs.;
|
||||
if (scan(token,2,'()')!!'.sas')=scan(paths[k],2,'/\') then
|
||||
do;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
end;
|
||||
else /* all other "regular" cases */
|
||||
do;
|
||||
if 0=H.find() then
|
||||
do;
|
||||
starts[n]+ -s;
|
||||
ends[n] + -e;
|
||||
write[n] + (s-e);
|
||||
select;
|
||||
when(write[n]<0)
|
||||
putlog "ERROR: Wrong tags order for " token=;
|
||||
when(write[n]>1)
|
||||
do;
|
||||
putlog "WARNING: Doubled value for tag" token=;
|
||||
putlog "WARNING- detected in line " _N_;
|
||||
putlog "WARNING- Check also counterpart block.";
|
||||
end;
|
||||
otherwise;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
/********************************************************/
|
||||
end;
|
||||
else
|
||||
do j = 1 to hbound(write);
|
||||
if write[j]>0 then
|
||||
do;
|
||||
length fvariable $ 4096;
|
||||
fvariable=catx("/",packagePath,paths[j]);
|
||||
file f FILEVAR=fvariable MOD;
|
||||
/*
|
||||
lineToPrintLen=(lengthn(lineToPrint));
|
||||
if lineToPrintLen then
|
||||
put @1 lineToPrint $varying4096. lineToPrintLen;
|
||||
else put;
|
||||
*/
|
||||
if firstLine[j] then
|
||||
do;
|
||||
put '/* File generated with help of SAS Packages Framework, version 20241207. */';
|
||||
firstLine[j]=0;
|
||||
end;
|
||||
put _infile_;
|
||||
end;
|
||||
end;
|
||||
run;
|
||||
|
||||
filename f clear;
|
||||
libname w clear;
|
||||
)));
|
||||
%put NOTE- --&sysmacroname.-END--;
|
||||
options &options_tmp2.;
|
||||
%ENDofsplitCodeForPackage:
|
||||
%mend splitCodeForPackage;
|
||||
|
||||
|
||||
/**/
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to unload SAS package, version 20240927. Run %unloadPackage() for help info.'
|
||||
des = 'Macro to unload SAS package, version 20241207. Run %unloadPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -35,7 +35,7 @@ des = 'Macro to unload SAS package, version 20240927. Run %unloadPackage() for h
|
||||
%put ### This is short help information for the `unloadPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to unload SAS packages, version `20240927` #;
|
||||
%put # Macro to unload SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
hashing_file() function, SAS 9.4M6 */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to verify SAS package with the hash digest, version 20240927. Run %verifyPackage() for help info.'
|
||||
des = 'Macro to verify SAS package with the hash digest, version 20241207. Run %verifyPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -28,7 +28,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20240927. Run %
|
||||
%put ### This is short help information for the `verifyPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to verify SAS package with it hash digest, version `20240927` #;
|
||||
%put # Macro to verify SAS package with it hash digest, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
1302
SPF/SPFinit.md
1302
SPF/SPFinit.md
File diff suppressed because it is too large
Load Diff
912
SPF/SPFinit.sas
912
SPF/SPFinit.sas
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ run;
|
||||
```
|
||||
SHA256 digest for SQLinDS: F*3C010734B76CA7459C4D35087C899121011CD4AA2932B56335FF11A805C8EF8D
|
||||
|
||||
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
|
||||
---
|
||||
|
||||
@@ -57,7 +57,7 @@ run;
|
||||
```
|
||||
SHA256 digest for DFA: F*012375D87F66EB3A7BF5DDD0CC5AEE28851733EE33CC63231DF9045BEB958168
|
||||
|
||||
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
|
||||
[Documentation for DFA](https://github.com/SASPAC/blob/main/dfa.md "Documentation for DFA")
|
||||
|
||||
---
|
||||
|
||||
@@ -82,7 +82,7 @@ SHA256 digest for DFA: F*012375D87F66EB3A7BF5DDD0CC5AEE28851733EE33CC63231DF9045
|
||||
```
|
||||
SHA256 digest for macroArray: F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790
|
||||
|
||||
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
|
||||
[Documentation for macroArray](https://github.com/SASPAC/blob/main/macroarray.md "Documentation for macroArray")
|
||||
|
||||
---
|
||||
|
||||
@@ -120,7 +120,7 @@ format x bool.;
|
||||
```
|
||||
SHA256 digest for BasePlus: F*DFA83F8E0D7424DEB63D49620392068BC68D766552E2804CB6B01DE8E5A87769
|
||||
|
||||
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
|
||||
---
|
||||
|
||||
@@ -135,7 +135,7 @@ SHA256 digest for BasePlus: F*DFA83F8E0D7424DEB63D49620392068BC68D766552E2804CB6
|
||||
|
||||
SHA256 digest for GSM: F*80197391195C3EC41BD436DF0C8802D3920E4D22B64009A7DE872FBDF8D4B86E
|
||||
|
||||
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
|
||||
[Documentation for GSM](https://github.com/SASPAC/blob/main/gsm.md "Documentation for GSM")
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user