From 2579b4c929f13cb6803282e1319b4d20bd902591 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Sat, 22 Jan 2022 17:16:08 +0000 Subject: [PATCH] feat: new mcf_length.sas fcmp macro --- all.sas | 80 ++++++++++++++++++++++++- fcmp/mcf_length.sas | 77 ++++++++++++++++++++++++ tests/crossplatform/mcf_length.test.sas | 50 ++++++++++++++++ 3 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 fcmp/mcf_length.sas create mode 100644 tests/crossplatform/mcf_length.test.sas diff --git a/all.sas b/all.sas index 216e642..ca6c030 100644 --- a/all.sas +++ b/all.sas @@ -22680,6 +22680,82 @@ run; %mend ml_json; /** + @file + @brief Returns the length of a numeric value + @details + Returns the length, in bytes, of a numeric value. If the value is + missing, then 0 is returned. + + The function itself takes the following (positional) parameters: + + | PARAMETER | DESCRIPTION | + |---|---| + | var | variable (or value) to be tested| + + Usage: + + %mcf_length(wrap=YES, insert_cmplib=YES) + + data _null_; + ina=1; + inb=10000000; + inc=12345678; + ind=.; + outa=mcf_length(ina); + outb=mcf_length(inb); + outc=mcf_length(inc); + outd=mcf_length(ind); + put (out:)(=); + run; + + Returns: + + > outa=3 outb=4 outc=5 outd=0 + + @param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper. + @param [out] insert_cmplib= (NO) Choose YES to insert the package into the + CMPLIB reference. + @param [out] lib= (work) The output library in which to create the catalog. + @param [out] cat= (sasjs) The output catalog in which to create the package. + @param [out] pkg= (utils) The output package in which to create the function. + Uses a 3 part format: libref.catalog.package + +

Related Macros

+ @li mcf_length.test.sas + +**/ + +%macro mcf_length(wrap=NO + ,insert_cmplib=NO + ,lib=WORK + ,cat=SASJS + ,pkg=UTILS +)/*/STORE SOURCE*/; + +%if &wrap=YES %then %do; + proc fcmp outlib=&lib..&cat..&pkg; +%end; + +function mcf_length(var); + if missing(var) then len=0; + else if trunc(var,3)=var then len=3; + else if trunc(var,4)=var then len=4; + else if trunc(var,5)=var then len=5; + else if trunc(var,6)=var then len=6; + else if trunc(var,7)=var then len=7; + else len=8; + return(len); +endsub; + +%if &wrap=YES %then %do; + quit; +%end; + +%if &insert_cmplib=YES %then %do; + options insert=(CMPLIB=(&lib..&cat)); +%end; + +%mend mcf_length;/** @file @brief Provides a replacement for the stpsrv_header function @details The stpsrv_header is normally a built-in function, used to set the @@ -22750,7 +22826,7 @@ run; %if %mf_existfunction(stpsrv_header)=1 %then %return; %if &wrap=YES %then %do; - proc fcmp outcat=&lib..&cat..&pkg; + proc fcmp outlib=&lib..&cat..&pkg; %end; function stpsrv_header(name $, value $); @@ -22828,7 +22904,7 @@ endsub; )/*/STORE SOURCE*/; %if &wrap=YES %then %do; - proc fcmp outcat=&lib..&cat..&pkg; + proc fcmp outlib=&lib..&cat..&pkg; %end; function mcf_string2file(filepath $, string $, mode $); diff --git a/fcmp/mcf_length.sas b/fcmp/mcf_length.sas new file mode 100644 index 0000000..b6688bd --- /dev/null +++ b/fcmp/mcf_length.sas @@ -0,0 +1,77 @@ +/** + @file + @brief Returns the length of a numeric value + @details + Returns the length, in bytes, of a numeric value. If the value is + missing, then 0 is returned. + + The function itself takes the following (positional) parameters: + + | PARAMETER | DESCRIPTION | + |---|---| + | var | variable (or value) to be tested| + + Usage: + + %mcf_length(wrap=YES, insert_cmplib=YES) + + data _null_; + ina=1; + inb=10000000; + inc=12345678; + ind=.; + outa=mcf_length(ina); + outb=mcf_length(inb); + outc=mcf_length(inc); + outd=mcf_length(ind); + put (out:)(=); + run; + + Returns: + + > outa=3 outb=4 outc=5 outd=0 + + @param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper. + @param [out] insert_cmplib= (NO) Choose YES to insert the package into the + CMPLIB reference. + @param [out] lib= (work) The output library in which to create the catalog. + @param [out] cat= (sasjs) The output catalog in which to create the package. + @param [out] pkg= (utils) The output package in which to create the function. + Uses a 3 part format: libref.catalog.package + +

Related Macros

+ @li mcf_length.test.sas + +**/ + +%macro mcf_length(wrap=NO + ,insert_cmplib=NO + ,lib=WORK + ,cat=SASJS + ,pkg=UTILS +)/*/STORE SOURCE*/; + +%if &wrap=YES %then %do; + proc fcmp outlib=&lib..&cat..&pkg; +%end; + +function mcf_length(var); + if missing(var) then len=0; + else if trunc(var,3)=var then len=3; + else if trunc(var,4)=var then len=4; + else if trunc(var,5)=var then len=5; + else if trunc(var,6)=var then len=6; + else if trunc(var,7)=var then len=7; + else len=8; + return(len); +endsub; + +%if &wrap=YES %then %do; + quit; +%end; + +%if &insert_cmplib=YES %then %do; + options insert=(CMPLIB=(&lib..&cat)); +%end; + +%mend mcf_length; \ No newline at end of file diff --git a/tests/crossplatform/mcf_length.test.sas b/tests/crossplatform/mcf_length.test.sas new file mode 100644 index 0000000..be1f3e6 --- /dev/null +++ b/tests/crossplatform/mcf_length.test.sas @@ -0,0 +1,50 @@ +/** + @file + @brief Testing mcf_length.sas macro + +

SAS Macros

+ @li mcf_length.sas + @li mp_assert.sas + +**/ + +%mcf_length(wrap=YES, insert_cmplib=YES) + +data test; + call symputx('null',mcf_length(.)); + call symputx('three',mcf_length(1)); + call symputx('four',mcf_length(10000000)); + call symputx('five',mcf_length(12345678)); + call symputx('six',mcf_length(1234567890)); + call symputx('seven',mcf_length(12345678901234)); + call symputx('eight',mcf_length(12345678901234567)); +run; + +%mp_assert( + iftrue=(%str(&null)=%str(0)), + desc=Check if NULL returns 0 +) +%mp_assert( + iftrue=(%str(&three)=%str(3)), + desc=Check for length 3 +) +%mp_assert( + iftrue=(%str(&four)=%str(4)), + desc=Check for length 4 +) +%mp_assert( + iftrue=(%str(&five)=%str(5)), + desc=Check for length 5 +) +%mp_assert( + iftrue=(%str(&six)=%str(6)), + desc=Check for length 6 +) +%mp_assert( + iftrue=(%str(&seven)=%str(7)), + desc=Check for length 3 +) +%mp_assert( + iftrue=(%str(&eight)=%str(8)), + desc=Check for length 8 +) \ No newline at end of file