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;