Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
mm_getstpcode.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Writes the code of an STP to an external file
4 @details Fetches the SAS code from a Stored Process where the code is stored
5 in metadata.
6
7 Usage:
8
9 %mm_getstpcode(tree=/some/meta/path
10 ,name=someSTP
11 ,outloc=/some/unquoted/filename.ext
12 )
13
14 @param [in] tree= The metadata path of the Stored Process (can also contain
15 name)
16 @param [in] name= Stored Process name. Leave blank if included above.
17 @param [out] outloc= (0) full and unquoted path to the desired text file.
18 This will be overwritten if it already exists.
19 @param [out] outref= (0) Fileref to which to write the code.
20 @param [out] showlog=(NO) Set to YES to print log to the window
21
22 <h4> SAS Macros </h4>
23 @li mf_getuniquefileref.sas
24
25 @author Allan Bowe
26
27**/
28
29%macro mm_getstpcode(
30 tree=/User Folders/sasdemo/somestp
31 ,name=
32 ,outloc=0
33 ,outref=0
34 ,mDebug=1
35 ,showlog=NO
36 );
37
38%local mD;
39%if &mDebug=1 %then %let mD=;
40%else %let mD=%str(*);
41%&mD.put Executing &sysmacroname..sas;
42%&mD.put _local_;
43
44%if %length(&name)>0 %then %let name=/&name;
45
46/* first, check if STP exists */
47%local tsuri;
48%let tsuri=stopifempty ;
49
50data _null_;
51 format type uri tsuri value $200.;
52 call missing (of _all_);
53 path="&tree&name(StoredProcess)";
54 /* first, find the STP ID */
55 if metadata_pathobj("",path,"StoredProcess",type,uri)>0 then do;
56 /* get sourcecode */
57 cnt=1;
58 do while (metadata_getnasn(uri,"Notes",cnt,tsuri)>0);
59 rc=metadata_getattr(tsuri,"Name",value);
60 put tsuri= value=;
61 if value="SourceCode" then do;
62 /* found it! */
63 rc=metadata_getattr(tsuri,"Id",value);
64 call symputx('tsuri',value,'l');
65 stop;
66 end;
67 cnt+1;
68 end;
69 end;
70 else put (_all_)(=);
71run;
72
73%if &tsuri=stopifempty %then %do;
74 %put %str(WARN)ING: &tree&name.(StoredProcess) not found!;
75 %return;
76%end;
77
78
79/**
80 * Now we can extract the textstore
81 */
82filename __getdoc temp lrecl=10000000;
83proc metadata
84 in="<GetMetadata><Reposid>$METAREPOSITORY</Reposid>
85 <Metadata><TextStore Id='&tsuri'/></Metadata>
86 <Ns>SAS</Ns><Flags>1</Flags><Options/></GetMetadata>"
87 out=__getdoc ;
88run;
89
90/* find the beginning of the text */
91%local start;
92data _null_;
93 infile __getdoc lrecl=10000;
94 input;
95 start=index(_infile_,'StoredText="');
96 if start then do;
97 call symputx("start",start+11);
98 *putlog '"' _infile_ '"';
99 end;
100 stop;
101
102%local outeng;
103%if "&outloc"="0" %then %let outeng=TEMP;
104%else %let outeng="&outloc";
105%local fref;
106%if &outref=0 %then %let fref=%mf_getuniquefileref();
107%else %let fref=&outref;
108
109/* read the content, byte by byte, resolving escaped chars */
110filename &fref &outeng lrecl=100000;
111data _null_;
112 length filein 8 fileid 8;
113 filein = fopen("__getdoc","I",1,"B");
114 fileid = fopen("&fref","O",1,"B");
115 rec = "20"x;
116 length entity $6;
117 do while(fread(filein)=0);
118 x+1;
119 if x>&start then do;
120 rc = fget(filein,rec,1);
121 if rec='"' then leave;
122 else if rec="&" then do;
123 entity=rec;
124 do until (rec=";");
125 if fread(filein) ne 0 then goto getout;
126 rc = fget(filein,rec,1);
127 entity=cats(entity,rec);
128 end;
129 select (entity);
130 when ('&amp;' ) rec='&' ;
131 when ('&lt;' ) rec='<' ;
132 when ('&gt;' ) rec='>' ;
133 when ('&apos;') rec="'" ;
134 when ('&quot;') rec='"' ;
135 when ('&#x0a;') rec='0A'x;
136 when ('&#x0d;') rec='0D'x;
137 when ('&#36;' ) rec='$' ;
138 when ('&#x09;') rec='09'x;
139 otherwise putlog "%str(WARN)ING: missing value for " entity=;
140 end;
141 rc =fput(fileid, substr(rec,1,1));
142 rc =fwrite(fileid);
143 end;
144 else do;
145 rc =fput(fileid,rec);
146 rc =fwrite(fileid);
147 end;
148 end;
149 end;
150 getout:
151 rc=fclose(filein);
152 rc=fclose(fileid);
153run;
154
155%if &showlog=YES %then %do;
156 data _null_;
157 infile &fref lrecl=32767 end=last;
158 input;
159 if _n_=1 then putlog '>>stpcodeBEGIN<<';
160 putlog _infile_;
161 if last then putlog '>>stpcodeEND<<';
162 run;
163%end;
164
165filename __getdoc clear;
166%if &outref=0 %then %do;
167 filename &fref clear;
168%end;
169
170%mend mm_getstpcode;