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

The intsList() macro function allows to print a list of 
integers starting from `start` up to `end` incremented by `by`
and separated by `sep=`.

If `start`, `end` or `by` are non-integers the are converted to integers.

See examples below for the details.

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

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

The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%intsList(
    start
  <,end>
  <,by>
  <,sep=>
)
~~~~~~~~~~~~~~~~~~~~~~~

**Arguments description**:

1. `start`       - *Required*, the first value of the list.
                   If `end` is missing then the list is generated 
                   from 1 to `start` by 1.

2. `end`         - *Required/Optional*, the last value of the list.

3. `by`          - *Required/Optional*, the increment of the list.
                   If missing then set to `1`. 
                   *Cannot* be equal to `0`.

* `s = %str( )`  - *Optional*, it is a separator between 
                   elements of the list. Default value is space.

---

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

%macro intsList(start,end,by,sep=%str( ));
  %if %superq(end)= %then
    %do;
      %let end = %superq(start);
      %let start = 1;
    %end;
  %if %superq(by)= %then
    %do;
      %let by = 1;
    %end;
  %let start=%sysfunc(inputn(%superq(start),best32.));
  %let end  =%sysfunc(inputn(%superq(end)  ,best32.));
  %let by   =%sysfunc(inputn(%superq(by)   ,best32.));
  %if .=&start. OR .=&end. OR 0=&by. OR .=&by. %then
    %do;
      %put WARNING: [&sysmacroname.] Invalid value of start, end, or by! Aborting!;
      %put WARNING- [&sysmacroname.] &=start. &=end. &=by.;
      %goto numbersEND;
    %end;
  /* ensure integers */
  %let start=%sysfunc(int(%superq(start)));
  %let end  =%sysfunc(int(%superq(end)  ));
  %let by   =%sysfunc(int(%superq(by)   ));
  %put NOTE: [&sysmacroname.] Generaling list of numbers from %superq(start) to %superq(end) by %superq(by);
  %if 0=&by. %then
    %do;
      %put WARNING: [&sysmacroname.] Walue of by cannot be 0! Aborting!;
      %goto numbersEND;
    %end;
%do;&start.%do start=%sysevalf(&start. + &by.) %to &end. %by &by.;%unquote(&sep.)&start.%end;%end;
%numbersEND:
%mend intsList;


/*
Error handling test:

%put %intsList(xx,yy);
%put %intsList(a,c,0);
*/


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

**EXAMPLE 1.** Simple list of integers from 1 to 10 by 1:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  %put %intsList(10);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 2.** Ten copies of `sashelp.class` in `test11` to `test20`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  data
    %zipEvalf(test, %intsList(11,20))
  ;
    set sashelp.class;
  run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 3.** Non-integers are converted to integers, the list is `1 3 5`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  %put %intsList(1.1,5.2,2.3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 4.** A list with a separator:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
  %put %intsList(1,5,2,sep=+);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---

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

/**###################################################################**/
/*                                                                     */
/*  Copyright Bartosz Jablonski, since 2023.                           */
/*                                                                     */
/*  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)                               */
/*                                                                     */
/**###################################################################**/

