/*** HELP START ***//*
 
## >>> `%symdelGlobal()` macro: <<< <a name="symdelglobal-macro"></a> #######################

The `%symdelGlobal()` macro deletes all global macro variables
created by the user. The only exceptions are read only variables
and variables the one which starts with SYS, AF, or FSP.
In that case a warning is printed in the log.

One temporary global macro variable `________________98_76_54_32_10_` 
and a dataset, in `work` library, named `_%sysfunc(datetime(),hex7.)`
are created and deleted during the process.

The `%symdelGlobal()` macro executes like a pure macro code.

### SYNTAX: ###################################################################

The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%symdelGlobal(
 info
)
~~~~~~~~~~~~~~~~~~~~~~~

**Arguments description**:

1. `info` - *Optional*, default value should be empty, 
            if set to `NOINFO` or `QUIET` then infos and 
            warnings about variables deletion are suspended. 

*//*** HELP END ***/

%macro symdelGlobal(INFO)
/des = 'The %symdelGlobal() macro deletes all global macro variables created by the user.'
;
%local _rc_;
%global ________________98_76_54_32_10_;
%let _rc_ = %sysfunc(dosubl(%nrstr(
options NOnotes NOsource ps=max ls=max;
%put;
%let ________________98_76_54_32_10_ = _%sysfunc(datetime(),hex7.);
filename &________________98_76_54_32_10_. TEMP lrecl = 50;

proc printto log = &________________98_76_54_32_10_.;
run;
%put _readonly_;
proc printto log = log;
run;

data work.&________________98_76_54_32_10_.;
  length name $ 32; keep name;
  infile &________________98_76_54_32_10_. lrecl = 50 end=EOF;
  input;
  /*put ">>" _infile_;*/
  if "GLOBAL" =: _infile_ then name = scan(_infile_, 2, " ");
run;
filename &________________98_76_54_32_10_.;

data _null_;
  if _N_ =  1 then
    do;
      declare hash H(dataset:"work.&________________98_76_54_32_10_.");
      H.defineKey("name");
      H.defineDone();
      call execute("proc delete data = work.&________________98_76_54_32_10_.; run;");
      call execute("%symdel ________________98_76_54_32_10_ / nowarn;");
      INFO + (upcase(symget("INFO")) not in ("NOINFO" "QUIET"));
    end;
  set sashelp.vmacro;
  where scope='GLOBAL' and offset = 0;
  _rc_ = H.check();
  /* ignores system and read-only macro variables */
  if (name in: ('SYS' 'AF' 'FSP') or 0 = _rc_) then 
    do;
      if INFO then 
        do;
          put "WARNING: " @; 
          if _rc_ = 0 then put "Readonly" @;
                      else put "System" @;
          put " macro variable " name "cannot be deleted.";
        end;
    end;
  else 
    do;
      if INFO then put "INFO: Removing macro variable " name +(-1) ".";
      call execute('%nrstr(%symdel ' || strip(name) || ' / nowarn;)');
    end;
run;
)));
%mend symdelGlobal;


/*** HELP START ***//*
 
### EXAMPLES AND USECASES: ####################################################

**EXAMPLE 1.** Basic use-case one. 
    Delete global macro variables, info notes 
    and warnings are printed in the log.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  %let a = 1;
  %let b = 2;
  %let c = 3;
  %let sys_my_var = 11;
  %let  af_my_var = 22;
  %let fsp_my_var = 33;
  %global / readonly read_only_x = 1234567890;

  %put _user_;

  %symdelGlobal();

  %put _user_;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**EXAMPLE 2.** Basic use-case two. 
    Delete global macro variables in quite mode
    No info notes and warnings are printed in the log.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  %let a = 1;
  %let b = 2;
  %let c = 3;
  %let sys_my_var = 11;
  %let  af_my_var = 22;
  %let fsp_my_var = 33;
  %global / readonly read_only_x = 1234567890;

  %put _user_;
  %put *%symdelGlobal(NOINFO)*;
  %put _user_;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---

*//*** HELP END ***/

/**###################################################################**/
/*                                                                     */
/*  Copyright Bartosz Jablonski, since October 2020.                   */
/*                                                                     */
/*  Code is under the MIT license. If you want - you can use it.       */
/*  But it comes with absolutely no warranty whatsoever.               */
/*  If you cause any damage or something - it will be your own fault.  */
/*  You've been warned! You are using it on your own risk.             */
/*  However, if you decide to use it don't forget to mention author.   */
/*  Bartosz Jablonski (yabwon@gmail.com)                               */
/*                                                                     */
/**###################################################################**/
