PL/I example of building a linked list

Following is an example of how to build a linked list in an Enterprise PL/I for z/OS or PL/I for MVS & VM program using callable services.
*PROCESS MACRO;
*Process lc(101),opt(0),s,map,list,stmt,a(f),ag         ;
 CESCSTO: PROC OPTIONS(MAIN);

    %INCLUDE  CEEIBMAW;
    %INCLUDE  CEEIBMCT;
    /****************************************************/
    /*Module/File Name: IBMLLST                         */
    /****************************************************/
    /**                                                **/
    /** FUNCTION : CEEGTST - obtain storage from user  **/
    /**                      heap for a linked list.   **/
    /**          : CEEFRST - free linked list storage  **/
    /**                                                **/
    /**   This example illustrates the construction of **/
    /**   a linked list using the Language Environment **/
    /**   storage management services.                 **/
    /**                                                **/
    /**   1.  Storage for each list element is         **/
    /**       allocated from the user heap,            **/
    /**                                                **/
    /**   2.  The list element is initialized and      **/
    /**       appended to the list.                    **/
    /**                                                **/
    /**   3.  After three members are appended, the    **/
    /**       list traversed and the data saved in     **/
    /**       each element is displayed.               **/
    /**                                                **/
    /**   4.  The linklist storage is freed.          **/
    /**                                                **/
    /****************************************************/
    /****************************************************/
    DCL NULL BUILTIN;
    /****************************************************/
    /*  Storage management parameters, including        */
    /*  pointers for the returned storage addresses.    */
    /****************************************************/
    DCL HEAPID FIXED BIN(31,0) INIT (0);  /* heap ID for user heap */
    DCL NBYTES FIXED BIN(31,0)            /* size of required heap */
               INIT (STORAGE(LIST_ITEM));
    DCL 01 FC,                      /* Feedback token */
           03 MsgSev    REAL FIXED BINARY(15,0),
           03 MsgNo     REAL FIXED BINARY(15,0),
           03 Flags,
              05 Case      BIT(2),
              05 Severity  BIT(3),
              05 Control   BIT(3),
           03 FacID     CHAR(3),    /* Facility ID */
           03 ISI                   /* Instance-Specific Information */
                        REAL FIXED BINARY(31,0);
    DCL ADDRSS POINTER,        /* Address of storage    */
        PREV   POINTER;        /* Address of prior item */
    DCL ANCHOR POINTER;        /* linklist anchor      */
    /****************************************************/
    /*  Declare linked list item as based structure.    */
    /****************************************************/
    DCL 01 LIST_ITEM BASED(ADDRSS), /* Map of list item */
           02  CHARDATA CHAR(80),
           02  NEXT_ITEM POINTER;
    PUT SKIP LIST('*****************************************');
    PUT SKIP LIST('PL/I linked list example is now in motion');
    PUT SKIP LIST('*****************************************');
    ANCHOR = NULL;
    DO LCOUNT = 1 TO 3;
       /****************************************************/
       /*   Call CEEGTST to get storage from user heap.    */
       /****************************************************/
       CALL CEEGTST ( HEAPID, NBYTES, ADDRSS, FC );
       IF  FBCHECK( FC, CEE000)  THEN  DO;

          /**********************************************/
          /* If storage is obtained successfully, the   */
          /* linked list elements are based on the      */
          /* address of the storage obtained.  Append   */
          /* element to end of list. The  list origin   */
          /* is pointed to by the variable ANCHOR.      */
          /**********************************************/
          IF ( ANCHOR = NULL )  THEN
              ANCHOR = ADDRSS;
          ELSE
             PREV ->NEXT_ITEM = ADDRSS;
          NEXT_ITEM = NULL;
          CHARDATA = 'This is list item number ' || LCOUNT;
          PREV = ADDRSS;
          END;
       ELSE  DO;
          PUT SKIP LIST ( 'Error ' || FC.MsgNo
             || ' in getting user storage' );
          STOP;
          END;
       END;
    /*****************************************************/
    /*  On completion of the above loop, we have the     */
    /*  following layout:                                */
    /*                                                   */
    /*  ANCHOR -> LIST_ITEM1 -> LIST_ITEM2 -> LIST_ITEM3 */
    /*                                                   */
    /*  Loop thru list items 1 thru 3 and print out the  */
    /*  identifying text written in the CHARDATA fields. */
    /*                                                   */
    /*  Test a counter variable to verify that three     */
    /*  items were indeed in the linked-list.            */
    /*****************************************************/
    ADDRSS = ANCHOR;
    LCOUNT = 0;
    DO UNTIL (ADDRSS = NULL);

       PUT SKIP LIST(CHARDATA);
       /*************************************************/
       /*   Call CEEFRST to free this piece of storage. */
       /*************************************************/
       CALL CEEFRST ( ADDRSS, FC );
       IF  FBCHECK( FC, CEE000)  THEN  DO;
          LCOUNT = LCOUNT + 1;
          END;
       ELSE  DO;
          PUT SKIP LIST ( 'Error' || FC.MsgNo
             || ' freeing storage from heap');
          STOP;
          END;
       ADDRSS = NEXT_ITEM;
       END;
    IF  LCOUNT = 3  THEN  DO;
       PUT SKIP LIST('**************************************');
       PUT SKIP LIST('PL/I linked list example is now ended.');
       PUT SKIP LIST('**************************************');
       END;

 END CESCSTO;