1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-11 06:24:35 +00:00

Merge pull request #183 from sasjs/feature/mf_getuniquelibref_safe_default

fix: Closes #182 - update to mf_getuniquelibref.sas
This commit is contained in:
Allan Bowe
2022-03-04 12:20:54 +02:00
committed by GitHub
5 changed files with 123 additions and 30 deletions

View File

@@ -204,6 +204,7 @@ When contributing to this library, it is therefore important to ensure that all
We are currently on major release v4. Breaking changes should be marked with the [deprecated](https://www.doxygen.nl/manual/commands.html#cmddeprecated) doxygen tag. The following changes are planned when the next major/breaking release (v5) becomes necessary:
* mf_getuniquelibref.sas to have the deprecated maxtried parameter removed (no longer needed)
* mp_testservice.sas to be renamed as mp_execute.sas (as it doesn't actually test anything)
* `insert_cmplib` option of mcf_xxx macros will be deprecated (the option is now checked automatically with value inserted only if needed)
* mcf_xxx macros to have `wrap=` option defaulted to YES for convenience. Set this option explicitly to avoid issues.

49
all.sas
View File

@@ -970,29 +970,46 @@ or %index(&pgm,/tests/testteardown)
> mclib3
@param prefix= first part of libref. Remember that librefs can only be 8 characters,
so a 7 letter prefix would mean that maxtries should be 10.
@param maxtries= the last part of the libref. Provide an integer value.
A blank value is returned if no usable libname is determined.
@param [in] prefix= (mclib) first part of the returned libref. As librefs can
be as long as 8 characters, a maximum length of 7 characters is premitted
for this prefix.
@param [in] maxtries= Deprecated parameter. Remains here to ensure a
non-breaking change. Will be removed in v5.
@version 9.2
@author Allan Bowe
**/
%macro mf_getuniquelibref(prefix=mclib,maxtries=1000);
%local x libref;
%let x=0;
%do x=0 %to &maxtries;
%if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
%let libref=&prefix&x;
%let rc=%sysfunc(libname(&libref,%sysfunc(pathname(work))));
%if &rc %then %put %sysfunc(sysmsg());
&prefix&x
%*put &sysmacroname: Libref &libref assigned as WORK and returned;
%local x;
%if ( %length(&prefix) gt 7 ) %then %do;
%put %str(ERR)OR: The prefix parameter cannot exceed 7 characters.;
0
%return;
%end;
%else %if (%sysfunc(NVALID(&prefix,v7))=0) %then %do;
%put %str(ERR)OR: Invalid prefix (&prefix);
0
%return;
%end;
%put unable to find available libref in range &prefix.0-&maxtries;
/* Set maxtries equal to '10 to the power of [# unused characters] - 1' */
%let maxtries=%eval(10**(8-%length(&prefix))-1);
%do x = 0 %to &maxtries;
%if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
&prefix&x
%return;
%end;
%let x = %eval(&x + 1);
%end;
%put %str(ERR)OR: No usable libref in range &prefix.0-&maxtries;
%put %str(ERR)OR- Try reducing the prefix or deleting some libraries!;
0
%mend mf_getuniquelibref;/**
@file mf_getuniquename.sas
@brief Returns a shortened (32 char) GUID as a valid SAS name
@@ -3146,7 +3163,9 @@ run;
%let ds=&syslast;
proc compare base=&scopeds compare=&ds;
proc compare
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
compare=&ds;
run;
%if &sysinfo=0 %then %do;

View File

@@ -14,27 +14,44 @@
> mclib3
@param prefix= first part of libref. Remember that librefs can only be 8 characters,
so a 7 letter prefix would mean that maxtries should be 10.
@param maxtries= the last part of the libref. Provide an integer value.
A blank value is returned if no usable libname is determined.
@param [in] prefix= (mclib) first part of the returned libref. As librefs can
be as long as 8 characters, a maximum length of 7 characters is premitted
for this prefix.
@param [in] maxtries= Deprecated parameter. Remains here to ensure a
non-breaking change. Will be removed in v5.
@version 9.2
@author Allan Bowe
**/
%macro mf_getuniquelibref(prefix=mclib,maxtries=1000);
%local x libref;
%let x=0;
%do x=0 %to &maxtries;
%if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
%let libref=&prefix&x;
%let rc=%sysfunc(libname(&libref,%sysfunc(pathname(work))));
%if &rc %then %put %sysfunc(sysmsg());
&prefix&x
%*put &sysmacroname: Libref &libref assigned as WORK and returned;
%local x;
%if ( %length(&prefix) gt 7 ) %then %do;
%put %str(ERR)OR: The prefix parameter cannot exceed 7 characters.;
0
%return;
%end;
%else %if (%sysfunc(NVALID(&prefix,v7))=0) %then %do;
%put %str(ERR)OR: Invalid prefix (&prefix);
0
%return;
%end;
%put unable to find available libref in range &prefix.0-&maxtries;
/* Set maxtries equal to '10 to the power of [# unused characters] - 1' */
%let maxtries=%eval(10**(8-%length(&prefix))-1);
%do x = 0 %to &maxtries;
%if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
&prefix&x
%return;
%end;
%let x = %eval(&x + 1);
%end;
%put %str(ERR)OR: No usable libref in range &prefix.0-&maxtries;
%put %str(ERR)OR- Try reducing the prefix or deleting some libraries!;
0
%mend mf_getuniquelibref;

View File

@@ -104,7 +104,9 @@
%let ds=&syslast;
proc compare base=&scopeds compare=&ds;
proc compare
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
compare=&ds;
run;
%if &sysinfo=0 %then %do;

View File

@@ -0,0 +1,54 @@
/**
@file
@brief Testing mf_getuniquelibref macro
@details To test performance you can also use the following macro:
<h4> SAS Macros </h4>
@li mf_getuniquelibref.sas
@li mp_assert.sas
@li mp_assertscope.sas
**/
/* check valid libs */
%mp_assertscope(SNAPSHOT)
%let libshort=%mf_getuniquelibref(prefix=lib);
%mp_assertscope(COMPARE,ignorelist=LIBSHORT)
libname &libshort (work);
%mp_assert(
iftrue=(&syscc=0),
desc=Checking for valid libref &libshort,
outds=work.test_results
)
%let lib7=%mf_getuniquelibref(prefix=libref7);
libname &lib7 (work);
%mp_assert(
iftrue=(&syscc=0),
desc=Checking for valid libref &lib7,
outds=work.test_results
)
/* check for invalid libs */
%let lib8=%mf_getuniquelibref(prefix=lib8char);
%mp_assert(
iftrue=(&lib8=0),
desc=Invalid prefix (8 chars),
outds=work.test_results
)
%let liblong=%mf_getuniquelibref(prefix=invalidlib);
%mp_assert(
iftrue=(&liblong=0),
desc=Checking for invalid libref (long),
outds=work.test_results
)
%let badlib=%mf_getuniquelibref(prefix=8adlib);
%mp_assert(
iftrue=(&badlib=0),
desc=Checking for invalid libref (8adlib),
outds=work.test_results
)