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  @li mp_abort.sas
25 
26  @author Allan Bowe
27 
28 **/
29 
30 %macro mm_getstpcode(
31  tree=/User Folders/sasdemo/somestp
32  ,name=
33  ,outloc=0
34  ,outref=0
35  ,mDebug=1
36  ,showlog=NO
37  );
38 
39 %local mD;
40 %if &mDebug=1 %then %let mD=;
41 %else %let mD=%str(*);
42 %&mD.put Executing &sysmacroname..sas;
43 %&mD.put _local_;
44 
45 %if %length(&name)>0 %then %let name=/&name;
46 
47 /* first, check if STP exists */
48 %local tsuri;
49 %let tsuri=stopifempty ;
50 
51 data _null_;
52  format type uri tsuri value $200.;
53  call missing (of _all_);
54  path="&tree&name(StoredProcess)";
55  /* first, find the STP ID */
56  if metadata_pathobj("",path,"StoredProcess",type,uri)>0 then do;
57  /* get sourcecode */
58  cnt=1;
59  do while (metadata_getnasn(uri,"Notes",cnt,tsuri)>0);
60  rc=metadata_getattr(tsuri,"Name",value);
61  &mD.put tsuri= value=;
62  if value="SourceCode" then do;
63  /* found it! */
64  rc=metadata_getattr(tsuri,"Id",value);
65  call symputx('tsuri',value,'l');
66  stop;
67  end;
68  cnt+1;
69  end;
70  end;
71  else put (_all_)(=);
72 run;
73 
74 %mp_abort(iftrue= (&tsuri=stopifempty)
75  ,mac=mm_getstpcode
76  ,msg=%str(&tree&name.(StoredProcess) not found!)
77 )
78 
79 /**
80  * Now we can extract the textstore
81  */
82 filename __getdoc temp lrecl=10000000;
83 proc 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 ;
88 run;
89 
90 /* find the beginning of the text */
91 %local start;
92 data _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 */
110 filename &fref &outeng lrecl=100000;
111 data _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);
153 run;
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 
165 filename __getdoc clear;
166 %if &outref=0 %then %do;
167  filename &fref clear;
168 %end;
169 
170 %mend mm_getstpcode;