From d0bde6259490b936fce086a0cc88b37e70052e77 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Tue, 24 Aug 2021 13:43:31 +0300 Subject: [PATCH] feat: adding APPEND option to mp_binarycopy.sas, and a new test (mp_binarycopy.test.sas). Closes #66 --- all.sas | 40 +++++++-- base/mp_binarycopy.sas | 40 +++++++-- tests/crossplatform/mp_binarycopy.test.sas | 99 ++++++++++++++++++++++ 3 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 tests/crossplatform/mp_binarycopy.test.sas diff --git a/all.sas b/all.sas index 0600468..2c58470 100644 --- a/all.sas +++ b/all.sas @@ -2413,10 +2413,29 @@ run; %mp_binarycopy(inloc="/home/me/blah.txt", outref=_webout) - @param inloc full, quoted "path/and/filename.ext" of the object to be copied - @param outloc full, quoted "path/and/filename.ext" of object to be created - @param inref can override default input fileref to avoid naming clash - @param outref an override default output fileref to avoid naming clash + To append to a file, use the mode option, eg: + + filename tmp1 temp; + filename tmp2 temp; + data _null_; + file tmp1; + put 'stacking'; + run; + + %mp_binarycopy(inref=tmp1, outref=tmp2, mode=APPEND) + %mp_binarycopy(inref=tmp1, outref=tmp2, mode=APPEND) + + + @param [in] inloc quoted "path/and/filename.ext" of the file to be copied + @param [out] outloc quoted "path/and/filename.ext" of the file to be created + @param [in] inref (____in) If provided, this fileref will take precedence over + the `inloc` parameter + @param [out] outref (____in) If provided, this fileref will take precedence + over the `outloc` parameter. It must already exist! + @param [in] mode (CREATE) Valid values: + @li CREATE - Create the file (even if it already exists) + @li APPEND - Append to the file (don't overwrite) + @returns nothing @version 9.2 @@ -2428,20 +2447,29 @@ run; ,outloc= /* full path and filename of object to be created */ ,inref=____in /* override default to use own filerefs */ ,outref=____out /* override default to use own filerefs */ + ,mode=CREATE )/*/STORE SOURCE*/; + %local mod outmode; + %if &mode=APPEND %then %do; + %let mod=mod; + %let outmode='a'; + %end; + %else %do; + %let outmode='o'; + %end; /* these IN and OUT filerefs can point to anything */ %if &inref = ____in %then %do; filename &inref &inloc lrecl=1048576 ; %end; %if &outref=____out %then %do; - filename &outref &outloc lrecl=1048576 ; + filename &outref &outloc lrecl=1048576 &mod; %end; /* copy the file byte-for-byte */ data _null_; length filein 8 fileid 8; filein = fopen("&inref",'I',1,'B'); - fileid = fopen("&outref",'O',1,'B'); + fileid = fopen("&outref",&outmode,1,'B'); rec = '20'x; do while(fread(filein)=0); rc = fget(filein,rec,1); diff --git a/base/mp_binarycopy.sas b/base/mp_binarycopy.sas index d964a73..abc7e91 100755 --- a/base/mp_binarycopy.sas +++ b/base/mp_binarycopy.sas @@ -9,10 +9,29 @@ %mp_binarycopy(inloc="/home/me/blah.txt", outref=_webout) - @param inloc full, quoted "path/and/filename.ext" of the object to be copied - @param outloc full, quoted "path/and/filename.ext" of object to be created - @param inref can override default input fileref to avoid naming clash - @param outref an override default output fileref to avoid naming clash + To append to a file, use the mode option, eg: + + filename tmp1 temp; + filename tmp2 temp; + data _null_; + file tmp1; + put 'stacking'; + run; + + %mp_binarycopy(inref=tmp1, outref=tmp2, mode=APPEND) + %mp_binarycopy(inref=tmp1, outref=tmp2, mode=APPEND) + + + @param [in] inloc quoted "path/and/filename.ext" of the file to be copied + @param [out] outloc quoted "path/and/filename.ext" of the file to be created + @param [in] inref (____in) If provided, this fileref will take precedence over + the `inloc` parameter + @param [out] outref (____in) If provided, this fileref will take precedence + over the `outloc` parameter. It must already exist! + @param [in] mode (CREATE) Valid values: + @li CREATE - Create the file (even if it already exists) + @li APPEND - Append to the file (don't overwrite) + @returns nothing @version 9.2 @@ -24,20 +43,29 @@ ,outloc= /* full path and filename of object to be created */ ,inref=____in /* override default to use own filerefs */ ,outref=____out /* override default to use own filerefs */ + ,mode=CREATE )/*/STORE SOURCE*/; + %local mod outmode; + %if &mode=APPEND %then %do; + %let mod=mod; + %let outmode='a'; + %end; + %else %do; + %let outmode='o'; + %end; /* these IN and OUT filerefs can point to anything */ %if &inref = ____in %then %do; filename &inref &inloc lrecl=1048576 ; %end; %if &outref=____out %then %do; - filename &outref &outloc lrecl=1048576 ; + filename &outref &outloc lrecl=1048576 &mod; %end; /* copy the file byte-for-byte */ data _null_; length filein 8 fileid 8; filein = fopen("&inref",'I',1,'B'); - fileid = fopen("&outref",'O',1,'B'); + fileid = fopen("&outref",&outmode,1,'B'); rec = '20'x; do while(fread(filein)=0); rc = fget(filein,rec,1); diff --git a/tests/crossplatform/mp_binarycopy.test.sas b/tests/crossplatform/mp_binarycopy.test.sas new file mode 100644 index 0000000..b456c21 --- /dev/null +++ b/tests/crossplatform/mp_binarycopy.test.sas @@ -0,0 +1,99 @@ +/** + @file + @brief Testing mp_binarycopy.sas macro + +

SAS Macros

+ @li mp_binarycopy.sas + @li mp_assert.sas + +**/ + + +/* TEST 1 - regular file copy */ +%let string1=test1; +filename tmp temp; +filename myref temp; +data _null_; + file tmp; + put "&string1"; +run; +%mp_binarycopy(inref=tmp, outref=myref) +data _null_; + infile myref; + input; + put _infile_; + call symputx('string1_check',_infile_); + stop; +run; +%mp_assert( + iftrue=("&string1"="&string1_check"), + desc=Basic String Compare, + outds=work.test_results +) + + +/* TEST 2 - File append */ +%let string2=test2; +%let path2=%sysfunc(pathname(work))/somefile.txt; +data _null_; + file "&path2"; + put "&string2"; +run; +%mp_binarycopy(inloc="&path2", outref=myref, mode=APPEND) +data _null_; + infile myref; + input; + put _infile_; + if _n_=2 then call symputx('string2_check',_infile_); +run; +%mp_assert( + iftrue=("&string2"="&string2_check"), + desc=Append Check (file to ref), + outds=work.test_results +) + +/* TEST 3 - File create (ref to existing file) */ +%let string3=test3; +%let path3=%sysfunc(pathname(work))/somefile3.txt; +filename tmp3 temp; +data _null_; + file tmp3; + put "&string3"; +run; +data _null_; + file "&path3"; + put "this should not be returned"; +run; +%mp_binarycopy(inref=tmp3, outloc="&path3") +data _null_; + infile "&path3"; + input; + put _infile_; + if _n_=1 then call symputx('string3_check',_infile_); +run; +%mp_assert( + iftrue=("&string3"="&string3_check"), + desc=Append Check (ref to existing file), + outds=work.test_results +) + +/* TEST 4 - File append (ref to file) */ +%let string4=test4; +%let string4_check=; +filename tmp4 temp; +data _null_; + file tmp4; + put "&string4"; +run; +%mp_binarycopy(inref=tmp4, outloc="&path3",mode=APPEND) +data _null_; + infile "&path3"; + input; + put _infile_; + if _n_=2 then call symputx('string4_check',_infile_); +run; +%mp_assert( + iftrue=("&string4"="&string4_check"), + desc=Append Check (ref to file), + outds=work.test_results +) \ No newline at end of file