Traversing lists

You can step through lists one entity at a time from one end to another. You would do this when populating auxiliary attributes of internal data structures, searching lists of requests for the “best” candidate according to a selection rule, and many other situations.

You can traverse a list using a “for” loop and the following system functions:

  • csfsls - Returns a pointer to the first entry.
  • csnxls - Returns a pointer to the next entry.
  • cslsls - Returns a pointer to the last entry.
  • csprls - Returns a pointer to the previous entry.

These traversal functions return a NULL pointer to indicate the end of the list. For example, consider the following code to traverse the global list of resources:


RESRC *rp;

for (rp = (RESRC *)csfsls(SSGVAR.sgresrc);
   rp != NULL;
   rp = (RESRC *)csnxls(rp)) 
{

   /* Processing for each resource in the list. */
}

You can modify the “for” loop to terminate the search when a specific material was located, either by adding an additional “and” clause to the continuation expression or by adding an “if” with a “break” inside the body of the loop. The following example illustrates traversing a list in reverse order and terminating either at the end of the list or at the first resource with an infinite flag equal to 1, i.e. infinite resource.


RESRC *rp, *prev_rp;

for (rp = (RESRC *)cslsls(SSGVAR.sgresrc);
   rp != NULL && rp->rsinffg == 1;
   rp = prev_rp) 
{

   prev_rp = (RESRC *)csprls(CSENTITY *rp):

   /* Processing for each resource in the list. */
  }

Note that the pointer to the next or previous entity in the list is always accessed from the pointer to the current entity. A serious problem would result if the current entity were removed from the list prior to getting the pointer to the next entity. In the previous example, this problem was solved by retrieving the pointer to the entity prior to the current entity before the processing within the loop. Thus, the processing may remove the current entity from the list if desired.