Compare commits

...

14 Commits

Author SHA1 Message Date
Bart Jablonski (yabwon)
00c63c4d8a SAS Packages Framework, version 20211216
**SAS Packages Framework**, version 20211216

- Bug fix in the `%verifyPackage()` macro
2021-12-16 10:40:29 +01:00
Bart Jablonski (yabwon)
9dedc53c31 **SAS Packages Framework**, version 20211216
**SAS Packages Framework**, version 20211216

- Bug fix in the `%verifyPackage()` macro
2021-12-16 10:36:08 +01:00
Bart Jablonski (yabwon)
a7d61f6026 SAS Packages Framework, version 220211216
**SAS Packages Framework**, version 220211216

- Bug fix in the `%verifyPackage()` macro
2021-12-16 10:15:25 +01:00
Bart Jablonski
9f92b5f5d4 Update gsm.md
link to video (in Polish) added
2021-12-02 08:54:39 +01:00
Bart Jablonski (yabwon)
a95c672693 Package BasePlus, version 1.12
Package BasePlus, version 1.12:

-BugFix in `%unzipLibrary()` macro.
2021-11-23 12:50:41 +01:00
Bart Jablonski (yabwon)
9bccc4329a Package BasePlus, version 1.11
Package BasePlus, version 1.11:

-Macro `%unzipLibrary()` updated.
2021-11-19 17:07:47 +01:00
yabwon
b76b1ed9eb Package BasePlus, version 1.1
Package BasePlus, version 1.1:

-New macro `%unzipLibrary()` added.
-Macro `%zipLibrary()` updated.
-The doc. updated.
2021-11-14 16:12:04 +01:00
yabwon
942879a5b8 Package BasePlus, version 1.0
Package BasePlus, version 1.0:

-New macro `%zipLibrary()` added.
-The doc. updated.
2021-11-13 22:51:01 +01:00
yabwon
fe631f9e44 Package GSM, version 0.17
Package GSM, version 0.17:

-New parameter `secret` added.
-The doc. updated.
2021-11-12 13:56:17 +01:00
yabwon
3f380b4e64 Package GSM, version 0.16
Package GSM, version 0.16:

-Check for the `SECURE` keyword added.
-Example in the doc. updated.
2021-11-12 11:43:12 +01:00
yabwon
02de8f0bc0 Package GSM, version 0.16
Package GSM, version 0.16:

-Check for the `SECURE` keyword added.
-Example in the doc. updated.
2021-11-12 11:11:39 +01:00
yabwon
7fa70d5ad4 SAS Packages Framework, version 20211111
**SAS Packages Framework**, version 20211111:

- The `packages` fileref can point to multiple directories now, e.g. `filename packages ("/dir/nr/one" "/dir/nr/two");`
- New macro `%extendPackagesFileref()` added,
- Help updated,

- Packages regenerated with new version of SPF:
   - DFA,
   - GSM,
   - MacroArray,
   - BasePlus,
   - dynMacroArray,
   - SQLinDS.
2021-11-10 20:21:07 +01:00
yabwon
98e822bde2 **GSM** (Generate Secure Macros) package, version 0.15
**GSM** (Generate Secure Macros) package, version 0.15

Doc. updated.
2021-11-05 13:48:39 +01:00
yabwon
2026254b96 BasePlus, version 0.994
**BasePlus, version 0.994**

Updates to the `%rainCloudPlot()` macro:
- new parameters,
-doc. updated.
2021-10-05 12:06:08 +02:00
18 changed files with 846 additions and 249 deletions

View File

@@ -8,7 +8,7 @@ A **SAS package** is an automatically generated, single, stand alone *zip* file
The *purpose of a package* is to be a simple, and easy to access, code sharing medium, which will allow: on the one hand, to separate the code complex dependencies created by the developer from the user experience with the final product and, on the other hand, reduce developer's and user's unnecessary frustration related to a remote deployment process.
In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. **The latest version** of SPF is **`20210528`**.
In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. **The latest version** of SPF is **`20211216`**.
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).
@@ -73,6 +73,8 @@ To create your own package:
---
**Update**\[November 11th, 2021\]**:** `%extendPackagesFileref()` **macro is available**.
**Update**\[October 15th, 2020\]**:** `%previewPackage()` **macro is available**.
**Update**\[September 11th, 2020\]**:** ` %loadPackageS()` and `%verifyPackage()` **macros are available**.
@@ -104,7 +106,7 @@ Currently the following packages are available (see the `./packages` directory):
set %SQL(select * from sashelp.class order by age);
run;
```
SHA256 digest for SQLinDS: 1853CD6262CF66582A33C373AA612CA714B61CB88A1C51745E7A57D5A03C39B4
SHA256 digest for SQLinDS: F2BE3CC68C9A34DD324FD35C8287A4F89737E2E28E806E0DD7FB0EBF60F7C569
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
@@ -116,7 +118,7 @@ SHA256 digest for MacroCore: A23C29529F3CE7D0C8BEE9545C5D22D5B5594907547374A5135
- **DFA** (Dynamic Function Arrays)\[0.5\], contains set of macros and FCMP functions which implement: a dynamically allocated array, a stack, a fifo queue, an ordered stack, and a priority queue, run `%helpPackage(DFA,createDFArray)` to find examples.
SHA256 digest for DFA: 22AB51B85E3344B8C0FB7AF164247881B656F5CBA88BBA974AD8BC41ED79327F
SHA256 digest for DFA: C32A81304A411C1EB6BA7B76EDB8D70550F3935F35A1506E2B8019A2036FB5FF
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
@@ -139,12 +141,12 @@ SHA256 digest for DFA: 22AB51B85E3344B8C0FB7AF164247881B656F5CBA88BBA974AD8BC41E
which = 1:H:2
);
```
SHA256 digest for macroArray: 849629D3AF3FE3AB45D86990E303F1D5E4D5F9F31C8ED6864C95B0DFAADCA445
SHA256 digest for macroArray: 9FE227EF3144431B51063D599148BDD8873509D1B32F1AC2979EC566E1BB1487
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
- **BasePlus**\[0.993\] adds a bunch of functionalities I am missing in BASE SAS, such as:
- **BasePlus**\[1.12\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```sas
call arrMissToRight(myArray);
call arrFillMiss(17, myArray);
@@ -157,22 +159,26 @@ string = catXFn("date9.", "#", myArray);
format x bool.;
%put %getVars(sashelp.class, pattern = ght$, sep = +, varRange = _numeric_);
%rainCloudPlot(sashelp.cars,DriveTrain,Invoice)
%zipLibrary(sashelp,libOut=work)
```
SHA256 digest for BasePlus: 5EAEF846754F19759C0492308478417C9667C9651F1EF14F70E4FF8AB4C857F6
SHA256 digest for BasePlus: 105F0CEB95C49102BDB085DF67C785301F623CB337D466F07B5E051626E4AE61
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
- **GSM** (Generate Secure Macros)\[0.14\], package allows
- **GSM** (Generate Secure Macros)\[0.17\], package allows
to create secured macros stored in SAS Proc FCMP functions.
The dataset with functions can be shared between different operating systems
and allows to generate macros on site without showing their code.
SHA256 digest for GSM: 93D88D4465B68984E938212241DE55C7B12EBC20601538553AC9E1AC0628C006
SHA256 digest for GSM: F6EE77A3C042E1E083E970BE255D126B52A75205DC1FB9A4A7337D0A89EEC7EB
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
- **dynMacroArray**\[0.2\], set of macros (wrappers for a hash table) emulating dynamic array in the data step (macro predecessor of DFA)
SHA256 digest for dynMacroArray: 67956116578E71327748B7EB3DAFF9D872DBC6F6EDD0DC11B7CF2A54FDA71785
SHA256 digest for dynMacroArray: 9FE227EF3144431B51063D599148BDD8873509D1B32F1AC2979EC566E1BB1487
### ======

View File

@@ -8,7 +8,8 @@
* [the `listPackages` macro](#listpackages)
* [the `verifyPackage` macro](#verifypackage)
* [the `previewPackage` macro](#previewPackage)
* [the `generatePackage` macro](#generatepackage)
* [the `generatePackage` macro](#generatepackage)
* [the `extendPackagesFileref` macro](#extendpackagesfileref)
* [Some more examples](#some-more-examples)
---
@@ -20,7 +21,7 @@ A **SAS package** is an automatically generated, single, stand alone *zip* file
The *purpose of a package* is to be a simple, and easy to access, code sharing medium, which will allow: on the one hand, to separate the code complex dependencies created by the developer from the user experience with the final product and, on the other hand, reduce developer's and user's unnecessary frustration related to a remote deployment process.
In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20210528`**.
In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20211216`**.
**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).
@@ -38,7 +39,7 @@ After assigning the directory do not change them when using the SPF since it may
## This is short help information for the `installPackage` macro <a name="installpackage"></a>
--------------------------------------------------------------------------------------------
Macro to install SAS packages, version `20210528`
Macro to install SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -48,6 +49,9 @@ After assigning the directory do not change them when using the SPF since it may
in the packages folder. The process of installation is equivalent with
manual downloading the package zip file into the packages folder.
In case the packages fileref is a multi-directory one the first directory
will be selected as a destination.
--------------------------------------------------------------------------------------------
### Parameters:
@@ -104,7 +108,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `helpPackage` macro <a name="helppackage"></a>
-------------------------------------------------------------------------------
Macro to get help about SAS packages, version `20210528`
Macro to get help about SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -174,7 +178,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `loadPackage` macro <a name="loadpackage"></a>
-------------------------------------------------------------------------------
Macro to *load* SAS packages, version `20210528`
Macro to *load* SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -247,7 +251,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `loadPackageS` macro <a name="loadpackages"></a>
-------------------------------------------------------------------------------
Macro wrapper for the loadPackage macro, version `20210528`
Macro wrapper for the loadPackage macro, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -296,7 +300,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `unloadPackage` macro <a name="unloadpackage"></a>
-------------------------------------------------------------------------------
Macro to unload SAS packages, version `20210528`
Macro to unload SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -361,7 +365,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `listPackages` macro <a name="listpackages"></a>
-----------------------------------------------------------------------------------------
Macro to list available SAS packages, version `20210528`
Macro to list available SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -402,7 +406,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `verifyPackage` macro <a name="verifypackage"></a>
-------------------------------------------------------------------------------
Macro to verify SAS package with it hash digest, version `20210528`
Macro to verify SAS package with it hash digest, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -410,6 +414,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
The `%verifyPackage()` macro generate package SHA256 hash
and compares it with the one provided by the user.
Works with `zip` packages only.
*Minimum SAS version required for the process is 9.4M6.*
@@ -455,7 +460,7 @@ filename packages "C:/SAS_PACKAGES"; %* set-up a directory for packages;
## This is short help information for the `previewPackage` macro <a name="previewpackage"></a>
-------------------------------------------------------------------------------
Macro to get previwe of a SAS packages, version `20210528`
Macro to get previwe of a SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -522,7 +527,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
## This is short help information for the `generatePackage` macro <a name="generatepackage"></a>
-------------------------------------------------------------------------------
Macro to generate SAS packages, version `20210528`
Macro to generate SAS packages, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -553,6 +558,8 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages;
- `packages=` Location of other packages for testing
if there are dependencies in loading the package.
Has to be a single directory, if more than one are
provided than only the first is used.
- `testResults=` Location where tests results should be stored,
if null (the default) then the session WORK is used.
@@ -693,6 +700,45 @@ All files have to have `.sas` extension. Other files are ignored.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------------------------------------------------------------------------------
## This is short help information for the `extendPackagesFileref` macro <a name="extendpackagesfileref"></a>
-----------------------------------------------------------------------------------------
Macro to list directories pointed by 'packages' fileref, version `20211216`
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
data, etc.) wrapped up together and embedded inside the zip.
The `%extendPackagesFileref()` macro lists directories pointed by
the packages fileref. It allows to add new dierctories to packages folder list.
### Parameters:
1. `packages` *Optional.* A valid fileref name, when empty the "packages" is used
When used as: `%extendPackagesFileref(HELP)` it displays this help information.
------------------------------------------------------------------------------------------
Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation`
to learn more.
### Example ###################################################################
Enabling the SAS Package Framework
from the local directory and adding
new directory.
Assume that the `SPFinit.sas` file
is located in one of "C:/SAS_PK1" or "C:/SAS_PK2" folders.
Run the following code in your SAS session:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
filename packages ("C:/SAS_PK1" "C:/SAS_PK2"); %* setup a directory for packages;
%include packages(SPFinit.sas); %* enable the framework;
filename packages ("D:/NEW_DIR" %extendPackagesFileref()); %* add new directory;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-------------------------------------------------------------------------------

View File

@@ -42,7 +42,7 @@
- to unload, or
- to generate SAS packages.
Version 20210528.
Version 20211216.
See examples below.
A SAS package is a zip file containing a group of files
@@ -81,7 +81,7 @@
*/
)/secure
/*** HELP END ***/
des = 'Macro to load SAS package, version 20210528. Run %loadPackage() for help info.'
des = 'Macro to load SAS package, version 20211216. Run %loadPackage() for help info.'
;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do;
@@ -96,7 +96,7 @@ des = 'Macro to load SAS package, version 20210528. Run %loadPackage() for help
%put ### This is short help information for the `loadPackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to *load* SAS packages, version `20210528` #;
%put # Macro to *load* SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -169,19 +169,35 @@ des = 'Macro to load SAS package, version 20210528. Run %loadPackage() for help
options &options_tmp.;
%GOTO ENDofloadPackage;
%end;
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
/* local variables for options */
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
%local _PackageFileref_;
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
data _null_; call symputX("_PackageFileref_", "P" !! put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
/* when the packages reference is multi-directory search for the first one containing the package */
data _null_;
exists = 0;
length packages $ 32767 p $ 4096;
packages = resolve(symget("path"));
do i = 1 to countw(packages, "()", "QS");
p = dequote(scan(packages, i, "()", "QS"));
exists + fileexist(catx("/", p, "%lowcase(&packageName.).&zip."));
if exists then leave;
end;
if exists then call symputx("path", p, "L");
run;
filename &_PackageFileref_. &ZIP.
/* put location of package myPackageFile.zip here */
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
@@ -223,10 +239,13 @@ des = 'Macro to load SAS package, version 20210528. Run %loadPackage() for help
filename &_PackageFileref_. clear;
%WrongVersionOFPackage:
/* restore optionos */
options ls = &ls_tmp. ps = &ps_tmp.
&notes_tmp. &source_tmp.
&stimer_tmp. &fullstimer_tmp.
msglevel=&msglevel_tmp.;
%ENDofloadPackage:
%mend loadPackage;
@@ -251,7 +270,7 @@ des = 'Macro to load SAS package, version 20210528. Run %loadPackage() for help
*/
)/secure
/*** HELP END ***/
des = 'Macro to unload SAS package, version 20210528. Run %unloadPackage() for help info.'
des = 'Macro to unload SAS package, version 20211216. Run %unloadPackage() for help info.'
;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do;
@@ -266,7 +285,7 @@ des = 'Macro to unload SAS package, version 20210528. Run %unloadPackage() for h
%put ### This is short help information for the `unloadPackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to unload SAS packages, version `20210528` #;
%put # Macro to unload SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -331,17 +350,34 @@ des = 'Macro to unload SAS package, version 20210528. Run %unloadPackage() for h
options &options_tmp.;
%GOTO ENDofunloadPackage;
%end;
/* local variables for options */
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
%local _PackageFileref_;
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
data _null_; call symputX("_PackageFileref_", "P" !! put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
/* when the packages reference is multi-directory search for the first one containing the package */
data _null_;
exists = 0;
length packages $ 32767 p $ 4096;
packages = resolve(symget("path"));
do i = 1 to countw(packages, "()", "QS");
p = dequote(scan(packages, i, "()", "QS"));
exists + fileexist(catx("/", p, "%lowcase(&packageName.).&zip."));
if exists then leave;
end;
if exists then call symputx("path", p, "L");
run;
filename &_PackageFileref_. &ZIP.
/* put location of package myPackageFile.zip here */
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
@@ -361,7 +397,9 @@ des = 'Macro to unload SAS package, version 20210528. Run %unloadPackage() for h
%end;
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist!;
filename &_PackageFileref_. clear;
options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp. msglevel = &msglevel_tmp.;
%ENDofunloadPackage:
%mend unloadPackage;
@@ -390,7 +428,7 @@ des = 'Macro to unload SAS package, version 20210528. Run %unloadPackage() for h
*/
)/secure
/*** HELP END ***/
des = 'Macro to get help about SAS package, version 20210528. Run %helpPackage() for help info.'
des = 'Macro to get help about SAS package, version 20211216. Run %helpPackage() for help info.'
;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do;
@@ -405,7 +443,7 @@ des = 'Macro to get help about SAS package, version 20210528. Run %helpPackage()
%put ### This is short help information for the `helpPackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to get help about SAS packages, version `20210528` #;
%put # Macro to get help about SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -475,17 +513,34 @@ des = 'Macro to get help about SAS package, version 20210528. Run %helpPackage()
options &options_tmp.;
%GOTO ENDofhelpPackage;
%end;
/* local variables for options */
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
%local _PackageFileref_;
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
data _null_; call symputX("_PackageFileref_", "P" !! put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
/* when the packages reference is multi-directory search for the first one containing the package */
data _null_;
exists = 0;
length packages $ 32767 p $ 4096;
packages = resolve(symget("path"));
do i = 1 to countw(packages, "()", "QS");
p = dequote(scan(packages, i, "()", "QS"));
exists + fileexist(catx("/", p, "%lowcase(&packageName.).&zip."));
if exists then leave;
end;
if exists then call symputx("path", p, "L");
run;
filename &_PackageFileref_. &ZIP.
/* put location of package myPackageFile.zip here */
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
@@ -505,7 +560,9 @@ des = 'Macro to get help about SAS package, version 20210528. Run %helpPackage()
%end;
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist!;
filename &_PackageFileref_. clear;
options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp. msglevel = &msglevel_tmp.;
%ENDofhelpPackage:
%mend helpPackage;
@@ -515,7 +572,7 @@ TODO:
- add MD5(&packageName.) value hash instead "package" word in filenames [DONE]
*/
/* Macros to install SAS packages, version 20210528 */
/* Macros to install SAS packages, version 20211216 */
/* 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
@@ -534,7 +591,7 @@ TODO:
/secure
minoperator
/*** HELP END ***/
des = 'Macro to install SAS package, version 20210528. Run %%installPackage() for help info.'
des = 'Macro to install SAS package, version 20211216. Run %%installPackage() for help info.'
;
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
%do;
@@ -549,7 +606,7 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%put ### This is short help information for the `installPackage` macro #;
%put #--------------------------------------------------------------------------------------------#;;
%put # #;
%put # Macro to install SAS packages, version `20210528` #;
%put # Macro to install SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -559,6 +616,9 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%put # in the packages folder. The process of installation is equivalent with #;
%put # manual downloading the package zip file into the packages folder. #;
%put # #;
%put # In case the packages fileref is a multi-directory one the first directory #;
%put # will be selected as a destination. #;
%put # #;
%put #--------------------------------------------------------------------------------------------#;
%put # #;
%put #### Parameters: #;
@@ -616,15 +676,19 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%put ;
options &options_tmp.;
%GOTO ENDofinstallPackage;
%end;
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
%end;
/* local variables for options */
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
/*
@@ -632,6 +696,12 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
https://blogs.sas.com/content/sasdummy/2011/06/17/how-to-use-sas-data-step-to-copy-a-file-from-anywhere/
*/
/* in case the 'packages' fileref is multi-directory the first directory will be selected as a destination */
data _null_;
/* get the firstPackagesPath */
call symputX("firstPackagesPath", dequote(scan(pathname("packages"), 1, "()", "QS")) ,"L");
run;
%if %superq(sourcePath)= %then
%do;
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/packages/;
@@ -660,7 +730,7 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
"https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas"
recfm=N lrecl=1;
filename &out
"%sysfunc(pathname(packages))/SPFinit.sas"
"&firstPackagesPath./SPFinit.sas"
recfm=N lrecl=1;
%end;
%else
@@ -673,7 +743,7 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%end;
&URLoptions.
recfm=N lrecl=1;
filename &out "%sysfunc(pathname(packages))/%lowcase(&packageName.).zip" recfm=N lrecl=1;
filename &out "&firstPackagesPath./%lowcase(&packageName.).zip" recfm=N lrecl=1;
%end;
/*
filename in list;
@@ -708,12 +778,13 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
if FEXIST("&out") = 0 then
do;
put @2 "Installing the &packageName. package.";
put @2 "Installing the &packageName. package"
/ @2 "in the &firstPackagesPath. directory.";
rc = FCOPY("&in", "&out");
end;
else if FEXIST("&out") = 1 then
do;
if symget("replace")="1" then
if symgetn("replace")=1 then
do;
put @2 "The following file will be replaced during "
/ @2 "instalation of the &packageName. package: "
@@ -737,10 +808,12 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%put *** %lowcase(&packageName.) end *******************************************;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
%end;
options ls = &ls_tmp. ps = &ps_tmp.
&notes_tmp. &source_tmp.
&stimer_tmp. &fullstimer_tmp.
msglevel=&msglevel_tmp.;
%ENDofinstallPackage:
%mend installPackage;
@@ -751,7 +824,7 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
The first one should be used to point local folder with packages.
The second is used internally by macros.
Do not use them otherwise than:
filename packages "C:/SAS_PACKAGES";
filename packages "</the/folder/with/sas/packages>";
since it may affect stability of the framework.
**/
@@ -843,23 +916,11 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
/*** HELP END ***/
/* optional - obsolete - deprecated;
libname packages "C:/SAS_PACKAGES/";
%include "%sysfunc(pathname(packages))/loadpackage.sas";
%loadPackage(SQLinDS)
%helpPackage(SQLinDS)
%unloadPackage(SQLinDS)
*/
/*** HELP START ***/
/* Macro to list SAS packages in packages folder.
Version 20210528
Version 20211216
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -879,7 +940,7 @@ des = 'Macro to install SAS package, version 20210528. Run %%installPackage() fo
%macro listPackages()/PARMBUFF
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20210528.'
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20211216.'
;
%if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then
%do;
@@ -894,7 +955,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 `20210528` #;
%put # Macro to list available SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -937,86 +998,103 @@ des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HE
%end;
%local ls_tmp ps_tmp notes_tmp source_tmp filesWithCodes;
%let filesWithCodes = WORK._%sysfunc(datetime(), hex16.)_;
%let filesWithCodes = WORK._%sysfunc(datetime(), hex16.)_;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
options NOnotes NOsource ls=MAX ps=MAX;
data _null_;
base = "%sysfunc(pathname(packages))";
length baseAll $ 32767;
baseAll = pathname("packages");
if base = " " then
if baseAll = " " then
do;
put "NOTE: The file reference PACKAGES is not assigned.";
stop;
end;
length folder $ 64 file $ 1024 folderRef fileRef $ 8;
do k = 1 to countw(baseAll, "()", "QS"); drop k;
base = dequote(scan(baseAll, k, "()", "QS"));
folderRef = "_%sysfunc(datetime(), hex6.)0";
length folder $ 64 file $ 1024 folderRef fileRef $ 8;
rc=filename(folderRef, base);
folderid=dopen(folderRef);
folderRef = "_%sysfunc(datetime(), hex6.)0";
putlog " ";
put "/*" 100*"+" ;
do i=1 to dnum(folderId); drop i;
folder = dread(folderId, i);
rc=filename(folderRef, base);
folderid=dopen(folderRef);
fileRef = "_%sysfunc(datetime(), hex6.)1";
rc = filename(fileRef, catx("/", base, folder));
fileId = dopen(fileRef);
putlog " ";
put "/*" 100*"+" ;
do i=1 to dnum(folderId); drop i;
EOF = 0;
if fileId = 0 and lowcase(scan(folder, -1, ".")) = 'zip' then
do;
file = catx('/',base, folder);
rc1 = filename("package", strip(file), 'zip', 'member="description.sas"');
rcE = fexist("package");
rc2 = filename("package", " ");
if i = 1 then
do;
put " #";
put " # Listing packages for: " base;
put " #";
end;
if rcE then /* if the description.sas exists in the zip then read it */
do;
putlog " * ";
length nn $ 96;
if (96-lengthn(file)) < 1 then
put " * " file;
else
do;
nn = repeat("*", (96-lengthn(file)));
put " * " file nn;
end;
infile _DUMMY_ ZIP FILEVAR=file member="description.sas" end=EOF;
do until(EOF);
folder = dread(folderId, i);
fileRef = "_%sysfunc(datetime(), hex6.)1";
rc = filename(fileRef, catx("/", base, folder));
fileId = dopen(fileRef);
EOF = 0;
if fileId = 0 and lowcase(scan(folder, -1, ".")) = 'zip' then
do;
file = catx('/',base, folder);
rc1 = filename("package", strip(file), 'zip', 'member="description.sas"');
rcE = fexist("package");
rc2 = filename("package", " ");
if rcE then /* if the description.sas exists in the zip then read it */
do;
putlog " * ";
length nn $ 96;
if (96-lengthn(file)) < 1 then
put " * " file;
else
do;
nn = repeat("*", (96-lengthn(file)));
put " * " file nn;
end;
infile _DUMMY_ ZIP FILEVAR=file member="description.sas" end=EOF;
do until(EOF);
input;
if lowcase(scan(_INFILE_,1,":")) in ("package" "title" "version" "author" "maintainer" "license") then
if strip(upcase(scan(_INFILE_,1,":"))) in ("PACKAGE" "TITLE" "VERSION" "AUTHOR" "MAINTAINER" "LICENSE") then
do;
_INFILE_ = scan(_INFILE_,1,":") !! ":" !! scan(_INFILE_,2,":");
putlog " * " _INFILE_;
end;
if upcase(strip(_INFILE_)) =: "DESCRIPTION START:" then leave;
if strip(upcase(strip(_INFILE_))) =: "DESCRIPTION START:" then leave;
end;
end;
end;
end;
rc = dclose(fileId);
rc = filename(fileRef);
end;
rc = dclose(fileId);
rc = filename(fileRef);
end;
putlog " * ";
put 100*"+" "*/";
rc = dclose(folderid);
rc = filename(folderRef);
end;
putlog " * ";
put 100*"+" "*/";
rc = dclose(folderid);
rc = filename(folderRef);
stop;
run;
options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
%ENDoflistPackages:
%mend listPackages;
@@ -1025,7 +1103,7 @@ options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
/* Macro to generate SAS packages.
Version 20210528
Version 20211216
A SAS package is a zip file containing a group
of SAS codes (macros, functions, data steps generating
@@ -1046,7 +1124,8 @@ options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
,testPackage=Y /* indicator if tests should be executed,
default value Y means "execute tests" */
,packages= /* location of other packages if there are
dependencies in loading */
dependencies in loading, must be a single directory
if more than one are provided only the first is used */
,testResults= /* location where tests results should be stored,
if null (the default) the WORK is used */
,sasexe= /* a DIRECTORY where the SAS binary is located,
@@ -1057,7 +1136,7 @@ options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
if set to DEF then the !SASROOT/sasv9.cfg is used */
)/secure minoperator
/*** HELP END ***/
des = 'Macro to generate SAS packages, version 20210528. Run %generatePackage() for help info.'
des = 'Macro to generate SAS packages, version 20211216. Run %generatePackage() for help info.'
;
%if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then
%do;
@@ -1072,7 +1151,7 @@ des = 'Macro to generate SAS packages, version 20210528. Run %generatePackage()
%put ### This is short help information for the `generatePackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to generate SAS packages, version `20210528` #;
%put # Macro to generate SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -1103,6 +1182,8 @@ des = 'Macro to generate SAS packages, version 20210528. Run %generatePackage()
%put # #;
%put # - `packages=` Location of other packages for testing #;
%put # if there are dependencies in loading the package. #;
%put # Has to be a single directory, if more than one are #;
%put # provided than only the first is used. #;
%put # #;
%put # - `testResults=` Location where tests results should be stored, #;
%put # if null (the default) then the session WORK is used. #;
@@ -1151,19 +1232,19 @@ filename &_LIC_. "&filesLocation./license.sas" lrecl = 1024;
infile &_DESCR_.;
input;
select;
when(upcase(scan(_INFILE_, 1, ":")) = "PACKAGE") call symputX("packageName", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "VERSION") call symputX("packageVersion", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "AUTHOR") call symputX("packageAuthor", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "MAINTAINER") call symputX("packageMaintainer", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "TITLE") call symputX("packageTitle", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "ENCODING") call symputX("packageEncoding", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "LICENSE") call symputX("packageLicense", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "REQUIRED") call symputX("packageRequired", scan(_INFILE_, 2, ":"),"L");
when(upcase(scan(_INFILE_, 1, ":")) = "REQPACKAGES") call symputX("packageReqPackages", scan(_INFILE_, 2, ":"),"L");
select( strip(upcase(scan(_INFILE_, 1, ":"))) );
when("PACKAGE") call symputX("packageName", scan(_INFILE_, 2, ":"),"L");
when("VERSION") call symputX("packageVersion", scan(_INFILE_, 2, ":"),"L");
when("AUTHOR") call symputX("packageAuthor", scan(_INFILE_, 2, ":"),"L");
when("MAINTAINER") call symputX("packageMaintainer", scan(_INFILE_, 2, ":"),"L");
when("TITLE") call symputX("packageTitle", scan(_INFILE_, 2, ":"),"L");
when("ENCODING") call symputX("packageEncoding", scan(_INFILE_, 2, ":"),"L");
when("LICENSE") call symputX("packageLicense", scan(_INFILE_, 2, ":"),"L");
when("REQUIRED") call symputX("packageRequired", scan(_INFILE_, 2, ":"),"L");
when("REQPACKAGES") call symputX("packageReqPackages", scan(_INFILE_, 2, ":"),"L");
/* stop at the beginning of description */
when ( upcase(scan(_INFILE_, 1, ":")) = "DESCRIPTION START" ) stop;
when("DESCRIPTION START") stop;
otherwise;
end;
run;
@@ -1191,6 +1272,7 @@ filename &_LIC_. "&filesLocation./license.sas" lrecl = 1024;
%put ERROR- Aborting.;
%abort;
%end;
/* test for package name */
%if %sysfunc(lengthn(&packageName.)) > 24 %then
%do;
@@ -1206,6 +1288,7 @@ filename &_LIC_. "&filesLocation./license.sas" lrecl = 1024;
%put WARNING: Package name is less than 3 characters.;
%put WARNING- Maybe consider some _meaningful_ name?;
%end;
/* test characters in package name */
%if %qsysfunc(lengthn(%qsysfunc(compress(&packageName.,,KDF)))) NE %qsysfunc(lengthn(&packageName.)) %then
%do;
@@ -1217,6 +1300,7 @@ filename &_LIC_. "&filesLocation./license.sas" lrecl = 1024;
%put ERROR- Aborting.;
%abort;
%end;
/* test first symbol in package name */
%if %qsubstr(&packageName.,1,1) IN (1 2 3 4 5 6 7 8 9 0) %then
%do;
@@ -1485,8 +1569,8 @@ title6 "MD5 hashed fileref of package lowcase name: &_PackageFileref_.";
or (%bquote(&packageReqPackages.) ne )
%then
%do;
title7 "Required SAS licences: %qsysfunc(compress(%bquote(&packageRequired.), %str(%'%")))" ; /* ' */
title8 "Required SAS packages: %qsysfunc(compress(%bquote(&packageReqPackages.),%str(%'%")))" ; /* " */
title7 "Required SAS licences: %qsysfunc(compress(%bquote(&packageRequired.), %str(%'%")))" ; /* ' */
title8 "Required SAS packages: %qsysfunc(compress(%bquote(&packageReqPackages.),%str(%'%")))" ; /* " */
%end;
@@ -1553,13 +1637,13 @@ data _null_;
file &zipReferrence.(packagemetadata.sas) encoding = &packageEncoding.;
put ' data _null_; '; /* simple "%local" returns error while loading package */
put ' call symputX("packageName", " ", "L");';
put ' call symputX("packageVersion", " ", "L");';
put ' call symputX("packageTitle", " ", "L");';
put ' call symputX("packageAuthor", " ", "L");';
put ' call symputX("packageMaintainer", " ", "L");';
put ' call symputX("packageEncoding", " ", "L");';
put ' call symputX("packageLicense", " ", "L");';
put ' call symputX("packageName", " ", "L");';
put ' call symputX("packageVersion", " ", "L");';
put ' call symputX("packageTitle", " ", "L");';
put ' call symputX("packageAuthor", " ", "L");';
put ' call symputX("packageMaintainer", " ", "L");';
put ' call symputX("packageEncoding", " ", "L");';
put ' call symputX("packageLicense", " ", "L");';
put ' run; ';
put ' %let packageName =' "&packageName.;";
@@ -1613,7 +1697,7 @@ data _null_;
put ' %include &_PackageFileref_.(packagemetadata.sas) / &source2.; ';
put ' filename &_PackageFileref_. clear; ';
/* test if required version of package is "good enough" */
/* test if required version of package is "good enough" */
put ' %if %sysevalf(&requiredVersion. > &packageVersion.) %then ';
put ' %do; ';
put ' %put ERROR: Required version is &requiredVersion.; ';
@@ -1651,7 +1735,7 @@ data _null_;
put ' %put NOTE- ' @; put "Author(s): &packageAuthor.; ";
put ' %put NOTE- ' @; put "Maintainer(s): &packageMaintainer.; ";
put ' %put NOTE- ;';
put ' %put NOTE- Write %nrstr(%%)helpPackage(' "&packageName." ') for the description;';
put ' %put NOTE- Run %nrstr(%%)helpPackage(' "&packageName." ') for the description;';
put ' %put NOTE- ;';
put ' %put NOTE- *** START ***; ' /;
@@ -1670,7 +1754,7 @@ data _null_;
%if %bquote(&packageRequired.) ne %then
%do;
put ' %put NOTE- *Testing required SAS components*%sysfunc(DoSubL( '; /* DoSubL() */
put ' %put NOTE- *Testing required SAS components*%sysfunc(DoSubL( '; /* <- DoSubL() is here */
put ' options nonotes nosource %str(;) ';
put ' options ls=max ps=max locale=en_US %str(;) ';
put ' /* temporary redirect log */ ';
@@ -1699,7 +1783,7 @@ data _null_;
put ' /* read in output from proc setinit */ ';
put ' infile _stinit_ end=eof %str(;) ';
put ' input %str(;) ';
/*put ' put "*> " _infile_ %str(;)';*/ /* for testing */
/*put ' put "*> " _infile_ %str(;) '; */ /* for testing */
put ' ';
put ' /* if component is in setinit remove it from checklist */ ';
put ' if _infile_ =: "---" then ';
@@ -2466,7 +2550,7 @@ data _null_;
put ' end ; ';
%end;
put 'put "***"; put "* SAS package generated by generatePackage, version 20210528 *"; put "***";';
put 'put "***"; put "* SAS package generated by generatePackage, version 20211216 *"; put "***";';
put 'run; ' /;
@@ -2668,6 +2752,13 @@ filename &zipReferrence. clear;
%put WARNING: ** NO TESTING WILL BE EXECUTED. **;
%GOTO NOTESTING;
%end;
/* in case the packages macrovariable is multi-directory the first directory will be selected */
data _null_;
call symputX("packages", dequote(scan(resolve(symget("packages")), 1, "()", "QS")) ,"L");
run;
/* check if systask is available */
%if %sysfunc(GETOPTION(XCMD)) = NOXCMD %then
%do;
@@ -2821,7 +2912,7 @@ filename currdir ".";
filename currdir list;
/* if your package uses any other packages this points to their location */
/* test if packages fileref exists and if do then use it */
/* test if packages fileref exists and, if do, use it */
/* if no one is provided the filesLocation is used as a replacement */
%if %bquote(&packages.)= %then %let packages=%sysfunc(pathname(packages));
%if %bquote(&packages.)= %then %let packages=&filesLocation.;
@@ -3236,7 +3327,7 @@ TODO: (in Polish)
*/
)/secure
/*** HELP END ***/
des = 'Macro to load multiple SAS packages at one run, version 20210528. Run %loadPackages() for help info.'
des = 'Macro to load multiple SAS packages at one run, version 20211216. Run %loadPackages() for help info.'
parmbuff
;
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
@@ -3252,7 +3343,7 @@ parmbuff
%put ### This is short help information for the `loadPackageS` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro wrapper for the loadPackage macro, version `20210528` #;
%put # Macro wrapper for the loadPackage macro, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -3300,6 +3391,7 @@ parmbuff
options &options_tmp.;
%GOTO ENDofloadPackageS;
%end;
%local lengthOfsyspbuff numberOfPackagesNames i packageElement packageName packageVersion;
%let lengthOfsyspbuff = %qsysfunc(length(&syspbuff.));
@@ -3318,6 +3410,7 @@ parmbuff
%loadPackage(%unquote(&packageName.), requiredVersion=%unquote(&packageVersion.))
%end;
%ENDofloadPackageS:
%mend loadPackageS;
@@ -3336,7 +3429,7 @@ parmbuff
hashing_file() function, SAS 9.4M6 */
)/secure
/*** HELP END ***/
des = 'Macro to verify SAS package with the hash digest, version 20210528. Run %verifyPackage() for help info.'
des = 'Macro to verify SAS package with the hash digest, version 20211216. Run %verifyPackage() for help info.'
;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do;
@@ -3351,7 +3444,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20210528. Run %
%put ### This is short help information for the `verifyPackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to verify SAS package with it hash digest, version `20210528` #;
%put # Macro to verify SAS package with it hash digest, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -3405,19 +3498,34 @@ des = 'Macro to verify SAS package with the hash digest, version 20210528. Run %
options &options_tmp.;
%GOTO ENDofverifyPackage;
%end;
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let stimer_tmp = %sysfunc(getoption(stimer));
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
%local _PackageFileref_;
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
data _null_; call symputX("_PackageFileref_", "P" !! put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
/* when the packages reference is multi-directory search for the first one containing the package */
data _null_;
exists = 0;
length packages $ 32767 p $ 4096;
packages = resolve(symget("path"));
do i = 1 to countw(packages, "()", "QS");
p = dequote(scan(packages, i, "()", "QS"));
exists + fileexist(catx("/", p, "%lowcase(&packageName.).zip"));
if exists then leave;
end;
if exists then call symputx("path", p, "L");
run;
filename &_PackageFileref_.
/* put location of package myPackageFile.zip here */
@@ -3476,6 +3584,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20210528. Run %
&notes_tmp. &source_tmp.
&stimer_tmp. &fullstimer_tmp.
msglevel=&msglevel_tmp.;
%ENDofverifyPackage:
%mend verifyPackage;
/**/
@@ -3504,7 +3613,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20210528. Run %
*/
)/secure
/*** HELP END ***/
des = 'Macro to preview content of a SAS package, version 20210528. Run %previewPackage() for help info.'
des = 'Macro to preview content of a SAS package, version 20211216. Run %previewPackage() for help info.'
;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do;
@@ -3519,7 +3628,7 @@ des = 'Macro to preview content of a SAS package, version 20210528. Run %preview
%put ### This is short help information for the `previewPackage` macro #;
%put #-------------------------------------------------------------------------------#;
%put # #;
%put # Macro to get previwe of a SAS packages, version `20210528` #;
%put # Macro to get previwe of a SAS packages, version `20211216` #;
%put # #;
%put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #;
@@ -3586,17 +3695,32 @@ des = 'Macro to preview content of a SAS package, version 20210528. Run %preview
options &options_tmp.;
%GOTO ENDofpreviewPackage;
%end;
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let ls_tmp = %sysfunc(getoption(ls));
%let ps_tmp = %sysfunc(getoption(ps));
%let notes_tmp = %sysfunc(getoption(notes));
%let source_tmp = %sysfunc(getoption(source));
%let msglevel_tmp = %sysfunc(getoption(msglevel));
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
%local _PackageFileref_;
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
data _null_; call symputX("_PackageFileref_", "P" !! put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
/* when the packages reference is multi-directory search for the first one containing the package */
data _null_;
exists = 0;
length packages $ 32767 p $ 4096;
packages = resolve(symget("path"));
do i = 1 to countw(packages, "()", "QS");
p = dequote(scan(packages, i, "()", "QS"));
exists + fileexist(catx("/", p, "%lowcase(&packageName.).&zip."));
if exists then leave;
end;
if exists then call symputx("path", p, "L");
run;
filename &_PackageFileref_. &ZIP.
/* put location of package myPackageFile.zip here */
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
@@ -3616,7 +3740,114 @@ des = 'Macro to preview content of a SAS package, version 20210528. Run %preview
%end;
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist!;
filename &_PackageFileref_. clear;
options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp. msglevel = &msglevel_tmp.;
%ENDofpreviewPackage:
%mend previewPackage;
/*** HELP START ***/
%macro extendPackagesFileref(
packages /* A valid fileref name,
when empty the "packages" value is used */
)/secure
/*** HELP END ***/
des = 'Macro to list directories pointed by "packages" fileref, version 20211216. Run %extendPackagesFileref(HELP) for help info.'
;
%if %QUPCASE(&packages.) = 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 `extendPackagesFileref` macro #;
%put #-----------------------------------------------------------------------------------------#;;
%put # #;
%put # Macro to list directories pointed by 'packages' fileref, version `20211216` #;
%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 embedded inside the zip. #;
%put # #;
%put # The `%nrstr(%%extendPackagesFileref())` macro lists directories pointed by #;
%put # the packages fileref. It allows to add new dierctories to packages folder list. #;
%put # #;
%put #### Parameters: #;
%put # #;
%put # 1. `packages` *Optional.* A valid fileref name, when empty the "packages" is used. #;
%put # Use case: #;
%put # `%nrstr(%%extendPackagesFileref()).` #;
%put # #;
%put # When used as: `%nrstr(%%extendPackagesFileref(HELP))` it displays this help information. #;
%put # #;
%put #-----------------------------------------------------------------------------------------#;
%put # #;
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
%put # to learn more. #;
%put # #;
%put #### Example ##############################################################################;
%put # #;
%put # Enabling the SAS Package Framework #;
%put # from the local directory and adding #;
%put # new directory. #;
%put # #;
%put # Assume that the `SPFinit.sas` file #;
%put # is located in one of "C:/SAS_PK1" or "C:/SAS_PK2" folders. #;
%put # #;
%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 ;
%put %nrstr( filename packages ("D:/NEW_DIR" %%extendPackagesFileref()); %%* add new directory; );
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
%put ###########################################################################################;
%put ;
options &options_tmp.;
%GOTO ENDextendPackagesFileref;
%end;
%if %superq(packages) = %then %let packages = packages;
%if %qsysfunc(pathname(&packages.)) ne %then
%do;
%if %qsubstr(%qsysfunc(pathname(&packages.)), 1, 1) = %str(%() %then
%do;
%local length;
%let length = %eval(%length(%qsysfunc(pathname(&packages.)))-2);
%unquote(%qsubstr(%qsysfunc(pathname(&packages.)), 2, &length.))
%end;
%else "%sysfunc(pathname(&packages.))";
%end;
%ENDextendPackagesFileref:
%mend extendPackagesFileref;
/* Examples:
filename packages "C:\";
%include packages(SPFinit.sas)
%extendPackagesFileref(HELP)
filename packages (%extendPackagesFileref() "D:\");
filename packages list;
filename packages clear;
filename packages "C:\";
filename packages ("D:\" %extendPackagesFileref());
filename packages list;
%put *%extendPackagesFileref()*;
*/
/**/

View File

@@ -18,7 +18,7 @@ data class;
WH = weight + height;
run;
```
SHA256 digest for SQLinDS: 1853CD6262CF66582A33C373AA612CA714B61CB88A1C51745E7A57D5A03C39B4
SHA256 digest for SQLinDS: F2BE3CC68C9A34DD324FD35C8287A4F89737E2E28E806E0DD7FB0EBF60F7C569
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
@@ -59,7 +59,7 @@ data _null_;
end;
run;
```
SHA256 digest for DFA: 22AB51B85E3344B8C0FB7AF164247881B656F5CBA88BBA974AD8BC41ED79327F
SHA256 digest for DFA: C32A81304A411C1EB6BA7B76EDB8D70550F3935F35A1506E2B8019A2036FB5FF
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
@@ -84,13 +84,13 @@ SHA256 digest for DFA: 22AB51B85E3344B8C0FB7AF164247881B656F5CBA88BBA974AD8BC41E
which = 1:H:2
);
```
SHA256 digest for macroArray: 849629D3AF3FE3AB45D86990E303F1D5E4D5F9F31C8ED6864C95B0DFAADCA445
SHA256 digest for macroArray: 70032D27081A0EE15BC82B8F14D2A61700FA7C1F0D88B4DB516AB433CD06C4D3
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
---
- **BasePlus**\[0.993\] adds a bunch of functionalities I am missing in BASE SAS, such as:
- **BasePlus**\[1.12\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```sas
call arrMissToRight(myArray);
call arrFillMiss(17, myArray);
@@ -103,19 +103,23 @@ string = catXFn("date9.", "#", myArray);
format x bool.;
%put %getVars(sashelp.class, pattern = ght$, sep = +, varRange = _numeric_);
%rainCloudPlot(sashelp.cars,DriveTrain,Invoice)
%zipLibrary(sashelp,libOut=work)
```
SHA256 digest for BasePlus: 5EAEF846754F19759C0492308478417C9667C9651F1EF14F70E4FF8AB4C857F6
SHA256 digest for BasePlus: 105F0CEB95C49102BDB085DF67C785301F623CB337D466F07B5E051626E4AE61
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
---
- **GSM** (Generate Secure Macros)\[0.14\], package allows
- **GSM** (Generate Secure Macros)\[0.17\], package allows
to create secured macros stored in SAS Proc FCMP functions.
The dataset with functions can be shared between different operating systems
and allows to generate macros on site without showing their code.
SHA256 digest for GSM: 93D88D4465B68984E938212241DE55C7B12EBC20601538553AC9E1AC0628C006
SHA256 digest for GSM: F6EE77A3C042E1E083E970BE255D126B52A75205DC1FB9A4A7337D0A89EEC7EB
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
@@ -123,6 +127,6 @@ SHA256 digest for GSM: 93D88D4465B68984E938212241DE55C7B12EBC20601538553AC9E1AC0
- **dynMacroArray**\[0.2\], set of macros (wrappers for a hash table) emulating dynamic array in the data step (macro predecessor of DFA)
SHA256 digest for dynMacroArray: 67956116578E71327748B7EB3DAFF9D872DBC6F6EDD0DC11B7CF2A54FDA71785
SHA256 digest for dynMacroArray: 9FE227EF3144431B51063D599148BDD8873509D1B32F1AC2979EC566E1BB1487
---

View File

@@ -1,3 +1,32 @@
/* 20211123 */
BasePlus: 105F0CEB95C49102BDB085DF67C785301F623CB337D466F07B5E051626E4AE61
/* 20211119 */
BasePlus: 55AC07F7322F504EF22C5D00D46587744CD373E70A83932F837EA8C6ECB6D987
/* 20211114 */
BasePlus: 319109732B5CBD99ADDA6D48EA26DA5236622F9C5D332F94EF282F1C9DCE73F9
/* 20211113 */
BasePlus: 4EDB786B9D6F6D6C5741B5CAC1CB169DD10D8196600B2CB385DDE479A54F0FA3
/* 20211112 */
GSM: F6EE77A3C042E1E083E970BE255D126B52A75205DC1FB9A4A7337D0A89EEC7EB
/* 20211111 */
BasePlus: B34E352EC52E05B8BBE1816E6104F47677CBFDEAF7CD71B8BF04FDBFA01B0EF0
DFA: C32A81304A411C1EB6BA7B76EDB8D70550F3935F35A1506E2B8019A2036FB5FF
dynMacroArray: 9FE227EF3144431B51063D599148BDD8873509D1B32F1AC2979EC566E1BB1487
GSM: BEFAA87266D6DBA3D5983117FC36A24DE03A2F93791AC786DCDB37571A4494AC
macroArray: 70032D27081A0EE15BC82B8F14D2A61700FA7C1F0D88B4DB516AB433CD06C4D3
SQLinDS: F2BE3CC68C9A34DD324FD35C8287A4F89737E2E28E806E0DD7FB0EBF60F7C569
/* 20211105 */
GSM: 3EAF6E93642CCA9B5B592DF9BED4C8B20B60BCD4B0434720D12D26096717C4A9
/* 20211005 */
BasePlus: D01BDFB50EF023EF51806F5F0ED664523C1A6F25AA2778808558C212E6D74725
/* 20211001 */
BasePlus: 5EAEF846754F19759C0492308478417C9667C9651F1EF14F70E4FF8AB4C857F6

View File

@@ -43,13 +43,14 @@
* [`%QzipEvalf()` macro](#qzipevalf-macro)
* [`%functionExists()` macro](#functionexists-macro)
* [`%RainCloudPlot()` macro](#raincloudplot-macro)
* [`%zipLibrary()` macro](#ziplibrary-macro)
* [`%unzipLibrary()` macro](#unziplibrary-macro)
* [License](#license)
---
# The BasePlus package [ver. 0.993] <a name="baseplus-package"></a> ###############################################
# The BasePlus package [ver. 1.12] <a name="baseplus-package"></a> ###############################################
The **BasePlus** package implements useful
functions and functionalities I miss in the BASE SAS.
@@ -65,7 +66,8 @@ Kudos to all who inspired me to generate this package:
*Paul Dorfman*,
*Richard DeVenezia*,
*Christian Graffeuille*,
*Allan Bowe*.
*Allan Bowe*,
*Anamaria Calai*.
---
@@ -168,7 +170,7 @@ Kudos to all who inspired me to generate this package:
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Example 7**: Deduplicate values from a space separated list.
**Example 7**: De-duplicate values from a space separated list.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%let list = 4 5 6 1 2 3 1 2 3 4 5 6;
%put *%dedupListS(&list.)*;
@@ -187,59 +189,71 @@ Kudos to all who inspired me to generate this package:
![Rain Cloud Plot](./baseplus_RainCloudPlot_Ex0_9.png)
**Example 10**: Zip SAS library.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(sashelp, libOut=work)
%unzipLibrary(%sysfunc(pathname(work)), zip=sashelp, mode=S, clean=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
Package contains:
1. macro deduplistc
2. macro deduplistp
3. macro deduplists
4. macro deduplistx
5. macro functionexists
6. macro getvars
7. macro qdeduplistx
8. macro qgetvars
9. macro qzipevalf
10. macro raincloudplot
11. macro symdelglobal
12. macro zipevalf
13. format bool
14. format boolz
15. format ceil
16. format floor
17. format int
18. functions arrfill
19. functions arrfillc
20. functions arrmissfill
21. functions arrmissfillc
22. functions arrmisstoleft
23. functions arrmisstoleftc
24. functions arrmisstoright
25. functions arrmisstorightc
26. functions bracketsc
27. functions bracketsn
28. functions catxfc
29. functions catxfi
30. functions catxfj
31. functions catxfn
32. functions deldataset
33. functions semicolonc
34. functions semicolonn
35. format brackets
36. format semicolon
37. proto qsortincbyprocproto
38. functions frommissingtonumberbs
39. functions fromnumbertomissing
40. functions quicksort4notmiss
41. functions quicksorthash
42. functions quicksorthashsddv
43. functions quicksortlight
1. macro deduplistc
2. macro deduplistp
3. macro deduplists
4. macro deduplistx
5. macro functionexists
6. macro getvars
7. macro qdeduplistx
8. macro qgetvars
9. macro qzipevalf
10. macro raincloudplot
11. macro symdelglobal
12. macro unziplibrary
13. macro zipevalf
14. macro ziplibrary
15. format bool
16. format boolz
17. format ceil
18. format floor
19. format int
20. function arrfill
21. function arrfillc
22. function arrmissfill
23. function arrmissfillc
24. function arrmisstoleft
25. function arrmisstoleftc
26. function arrmisstoright
27. function arrmisstorightc
28. function bracketsc
29. function bracketsn
30. function catxfc
31. function catxfi
32. function catxfj
33. function catxfn
34. function deldataset
35. function semicolonc
36. function semicolonn
37. format brackets
38. format semicolon
39. proto qsortincbyprocproto
40. function frommissingtonumberbs
41. function fromnumbertomissing
42. function quicksort4notmiss
43. function quicksorthash
44. function quicksorthashsddv
45. function quicksortlight
*SAS package generated by generatePackage, version 20210528*
*SAS package generated by generatePackage, version 20211111*
The SHA256 hash digest for package BasePlus:
`5EAEF846754F19759C0492308478417C9667C9651F1EF14F70E4FF8AB4C857F6`
`105F0CEB95C49102BDB085DF67C785301F623CB337D466F07B5E051626E4AE61`
---
# Content description ############################################################################################
@@ -3015,7 +3029,11 @@ The basic syntax is the following, the `<...>` means optional parameters:
<,formated=>
<,y2axis=>
<,y2axisLevels=>
<,y2axisValueAttrs=>
<,xaxisValueAttrs=>
<,xaxisTickstyle=>
<,VSCALE=>
<,KERNEL_K=>
<,KERNEL_C=>
@@ -3109,6 +3127,17 @@ The basic syntax is the following, the `<...>` means optional parameters:
Indicates if the number of expected levels of values printed
on the right vertical axix.
* `y2axisValueAttrs` - *Optional*, default value `Color=Grey`.
Allows to modify Y2 axis values attributes.
* `xaxisValueAttrs` - *Optional*, default value `Color=Grey`.
Allows to modify X axis values attributes.
* `xaxisTickstyle` - *Optional*, default value `INSIDE`.
Allows to modify X axis tick style.
Allowed values are `OUTSIDE`, `INSIDE`, `ACROSS`, and `INBETWEEN`.
*For SAS previous to* **9.4M5** *set to missing!*
***Stat related options***:
* `VSCALE` - *Optional*, default value `Proportion`.
@@ -3132,7 +3161,9 @@ The basic syntax is the following, the `<...>` means optional parameters:
* `cleanTempData` - *Optional*, default value `1`.
Indicates if temporary data sets should be deleted.
**NOTES:**
---
### NOTES: ###################################################################
* Default value of the `title` option is:
`%nrstr(title1 JUSTIFY=C "Rain Cloud plot for &list_g. by " %unquote(&xLabel.);)`
@@ -3159,13 +3190,21 @@ The basic syntax is the following, the `<...>` means optional parameters:
`BlueViolet`, `RoyalBlue`, `OliveDrab`, `Gold`, `HotPink`, `Crimson`,
`MediumPurple`, `CornflowerBlue`, `YellowGreen`, `Goldenrod`, `Orchid`, `IndianRed`.
* The box-plot has the following interpretation:
- left vertical bar indicates the minimum,
- left whisker line starts at `max(Q1 - 1.5IQR, minimum)` and ends at lower quartile (Q1),
- diamond indicates mean,
- vertical bar inside of the box indicates median.
- right whisker line starts at upper quartile (Q3) and ends at `min(Q3 + 1.5IQR, maximum)`,
- right vertical bar indicates the maximum.
### BOX-AND-WHISKERS PLOT: ###################################################################
The box-and-whiskers plot has the following interpretation:
- left vertical bar indicates the minimum,
- left whisker line starts at `max(Q1 - 1.5IQR, minimum)` and ends at lower quartile (Q1),
- diamond indicates mean,
- vertical bar inside of the box indicates median,
- right whisker line starts at upper quartile (Q3) and ends at `min(Q3 + 1.5IQR, maximum)`,
- right vertical bar indicates the maximum.
With above setup it may happen that
there is a gap between the minimum marker and the beginning of the left whisker
or
there is a gap between the end of the right whisker and the maximum marker.
See examples below.
---
@@ -3229,6 +3268,233 @@ The output:
![Example 2b](./baseplus_RainCloudPlot_Ex2b.png)
---
## >>> `%zipLibrary()` macro: <<< <a name="ziplibrary-macro"></a> #######################
The zipLibrary() macro allows to zip content of a SAS library.
Files can be zipped into a single file (named as the input library)
or into multiple files (named as "dataset.sas7bdat.zip").
If a file is indexed also the index file is zipped.
Source files can be deleted after compression.
Status of compression and processing time is reported.
See examples below for the details.
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(
lib
<,mode=>
<,clean=>
<,libOut=>
<,compression=>
)
~~~~~~~~~~~~~~~~~~~~~~~
**Arguments description**:
1. `lib` - *Required*, a name of the library to be zipped.
Must be a valid SAS V7, V8, or V9 library.
* `mode = S` - *Optional*, default value is `S`,
indicates mode of compression
generates single zip file (`SINGLE/S`)
or multiple files (`MULTI/M`)
* `clean = 0` - *Optional*, default value is `0`,
should datasets be deleted after zipping?
`1` means *yes*, `0` means *no*.
* `libOut =` - *Optional*, default value is empty,
output library for a single zip file.
* `compression =` - *Optional*, default value is `6`,
specifies the compression level
`0` to `9`, where `0` is no compression
and `9` is maximum compression.
### EXAMPLES AND USECASES: ####################################################
**EXAMPLE 1.** Generate data:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
options dlcreatedir;
libname test1 "%sysfunc(pathname(work))/test1";
libname test2 "%sysfunc(pathname(work))/test2";
libname test3 (test1 test2);
libname test4 "%sysfunc(pathname(work))/test4";
options nodlcreatedir;
%put %sysfunc(pathname(test3));
%put %sysfunc(pathname(test4));
data
test1.A(index=(model))
test1.B
test2.C
test2.D(index=(model make io=(invoice origin)))
;
set sashelp.cars;
run;
data test1.B2 / view=test1.B2;
set test1.B;
output;
output;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 2.** Zip content of test3 library
into the same location in one zip file:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(test3)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 3.** Zip content of test3 library
into the same location in multiple zip files:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(test3, mode=MULTI)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 4.** Zip content of test3 library
with maximum compression level
into different location in one zip file
and delete source files:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(test3, clean=1, libOut=test4, compression=9)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
## >>> `%unzipLibrary()` macro: <<< <a name="unziplibrary-macro"></a> #######################
The unzipLibrary() macro allows to unzip content of a SAS library.
It is a *counterpart* to the `%zipLibrary()` macro and is *not* intended to work
with zip files generated by other software (though it may in some cases).
Files can be unzipped from a single file
or from multiple files (named e.g. "dataset.sas7bdat.zip").
If a file is indexed also the index file is unzipped.
Source files can be deleted after decompression.
Status of decompression and processing time is reported.
See examples below for the details.
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%unzipLibrary(
path
<,zip=>
<,mode=>
<,clean=>
<,libOut=>
)
~~~~~~~~~~~~~~~~~~~~~~~
**Arguments description**:
1. `path` - *Required*, a path pointing to zipped file(s) location.
* `zip =` - *Optional*, When `mode=S` a name of the
zip file containing SAS files to be unzipped.
* `mode = S` - *Optional*, default value is `S`,
indicates mode of decompression
read from a single zip file (`SINGLE/S`)
or from multiple files (`MULTI/M`)
* `clean = 0` - *Optional*, default value is `0`,
should zip files be deleted after unzipping?
`1` means *yes*, `0` means *no*.
* `libOut =` - *Optional*, default value is empty,
output library for a single zip file
decompression.
### EXAMPLES AND USECASES: ####################################################
**EXAMPLE 1.** Generate data:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
options dlcreatedir;
libname test1 "%sysfunc(pathname(work))/test1";
libname test2 "%sysfunc(pathname(work))/test2";
libname test3 (test1 test2);
libname test4 "%sysfunc(pathname(work))/test4";
options nodlcreatedir;
%put %sysfunc(pathname(test3));
%put %sysfunc(pathname(test4));
data
test1.A(index=(model))
test1.B
test2.C
test2.D(index=(model make io=(invoice origin)))
;
set sashelp.cars;
run;
data test1.B2 / view=test1.B2;
set test1.B;
output;
output;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 2.** Use data from Example 1.
First zip content of the `test3` library
to `test4` location into one zip file
and delete source files.
Next unzip `test3.zip` library into the
`test4` location and delete the zip file.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(test3, clean=1, libOut=test4)
%unzipLibrary(%sysfunc(pathname(test4)), zip=test3, clean=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 3.** Use data from Example 1.
First zip content of the `test1` library
into multiple zip files and delete source files.
Next unzip `*.zip` files in `test1`
location and delete zipped files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(test1, mode=M, clean=1)
%unzipLibrary(%sysfunc(pathname(test1)), mode=M, clean=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 4.** First zip content of the `sashelp` library
into `work` library.
Next unzip `sashelp.zip` file in `work`
location and delete zip file.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%zipLibrary(sashelp, mode=S, clean=0, libOut=work)
%unzipLibrary(%sysfunc(pathname(work)), zip=sashelp, mode=S, clean=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
## License ####################################################################

Binary file not shown.

View File

@@ -52,10 +52,10 @@ Package contains:
12. exec generatearrays
13. clean generatearrays
*SAS package generated by generatePackage, version 20210109*
*SAS package generated by generatePackage, version 20211111*
The SHA256 hash digest for package BasePlus:
`22AB51B85E3344B8C0FB7AF164247881B656F5CBA88BBA974AD8BC41ED79327F`
`C32A81304A411C1EB6BA7B76EDB8D70550F3935F35A1506E2B8019A2036FB5FF`
---
# Content description ############################################################################################

Binary file not shown.

Binary file not shown.

View File

@@ -8,7 +8,7 @@
---
# The GSM package [ver. 0.14] <a name="gsm-package"></a> ###############################################
# The GSM package [ver. 0.17] <a name="gsm-package"></a> ###############################################
The **GSM** (a.k.a. *Generate Secure Macros*) package allows
to create secured macros stored in SAS Proc FCMP functions.
@@ -42,6 +42,7 @@ run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See examples for more details.
Recording of presentation with "how it works" description, in Polish, is avaliable [here](https://www.youtube.com/watch?v=LtaWPe2sgRY&t=1s).
*How to use it:*
- Copy all files with your secured macros code into a directory.
@@ -65,10 +66,10 @@ Package contains:
Required SAS Components:
`Base SAS Software`
* SAS package generated by generatePackage, version 20210528 *
* SAS package generated by generatePackage, version 20211111 *
The SHA256 hash digest for package BasePlus:
`93D88D4465B68984E938212241DE55C7B12EBC20601538553AC9E1AC0628C006`
The SHA256 hash digest for package GSM:
`F6EE77A3C042E1E083E970BE255D126B52A75205DC1FB9A4A7337D0A89EEC7EB`
## >>> `%GSM()` macro: <<< <a name="gsm-macro"></a> #######################
@@ -115,6 +116,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
<,source2=>
<,outpath=>
<,encodingRestricted=>
<,secret=>
)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -142,6 +144,13 @@ The basic syntax is the following, the `<...>` means optional parameters:
encoding of the session which generates the dataset then
the generateMacros() function will not execute macro code.
* `secret=` - *Optional*, the default value is null, in such case the
secret is generated from the `sha256(datetime(), hex32.)` function
and is printed in the log. When not null then should be
alphanumerical constant. Non-alphanumerical characters are removed.
Required to execute the `resolve()` function.
User who do not know the value will not be able
to run the `_maxro_XX_()` function.
---
@@ -178,8 +187,8 @@ data _null_;
put _infile_;
cards4;
%macro xyz(x) / SECURE;
%do i = 1 to &x.;
%put &i=;
%do i = 1 %to &x.;
%put &=i;
%end;
%mend;
;;;;
@@ -214,6 +223,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
<,outlib=work.generateMacros.secure>
<,source2=>
<,fileNameCode=FNC>
<,secret=123456789>
)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -238,6 +248,11 @@ The basic syntax is the following, the `<...>` means optional parameters:
* `fileNameCode=` - *Optional*, the default value is `FNC`.
Internal fileref.
* `secret=` - *Optional*, internal, the default value is `1234567890`.
Alphanumerical constant required to execute the `resolve()`
function. User who do not know the value will not be able
to run the `_maxro_XX_()` function.
---
@@ -263,4 +278,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
---

Binary file not shown.

View File

@@ -66,10 +66,10 @@ Package contains:
Required SAS Components:
*Base SAS Software*
*SAS package generated by generatePackage, version 20210109.*
*SAS package generated by generatePackage, version 20211111.*
The SHA256 hash digest for package macroArray:
`849629D3AF3FE3AB45D86990E303F1D5E4D5F9F31C8ED6864C95B0DFAADCA445`
`70032D27081A0EE15BC82B8F14D2A61700FA7C1F0D88B4DB516AB433CD06C4D3`
---
# Content description ############################################################################################

Binary file not shown.

View File

@@ -46,10 +46,10 @@ Package contains:
Required SAS Components:
*Base SAS Software*
*SAS package generated by generatePackage, version 20210109*
*SAS package generated by generatePackage, version 20211111*
The SHA256 hash digest for package SQLinDS:
`1853CD6262CF66582A33C373AA612CA714B61CB88A1C51745E7A57D5A03C39B4`
`F2BE3CC68C9A34DD324FD35C8287A4F89737E2E28E806E0DD7FB0EBF60F7C569`
---
# Content description ############################################################################################

Binary file not shown.