/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/*	(c) Copyright Systems Integration Specialists Company, Inc.,	*/
/*	1998 All Rights Reserved					*/
/*									*/
/* MODULE NAME : mvl_ijou.c						*/
/* PRODUCT(S)  : Lean-T Stack						*/
/*									*/
/* MODULE DESCRIPTION :							*/
/*	Functions to automatically build a ReadJournal response,	*/
/*	assuming the Journal is modeled as a linked list of journal	*/
/*	entries.							*/
/*									*/
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE :				*/
/*	u_mvl_start_jread						*/
/*	u_mvl_get_next_jread_entry					*/
/*	u_mvl_free_jread_entry						*/
/*	u_mvl_end_jread							*/
/*									*/
/* MODIFICATION LOG :							*/
/*  Date     Who   Rev     Comments					*/
/* --------  ---  ------   -------------------------------------------  */
/* 03/11/04  GLB     07    Remove "thisFileName"                    	*/
/* 04/14/00  JRB     06    Lint cleanup.				*/
/* 01/21/00  MDE     05    Now use MEM_SMEM for dynamic memory		*/
/* 09/13/99  MDE     04    Added SD_CONST modifiers			*/
/* 11/16/98  MDE     03    Renamed internal functions (prefix '_')	*/
/* 10/29/98  JRB     02    Delete unnecessary includes.			*/
/* 10/09/98  JRB     01    Created					*/
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"

#include "mmsdefs.h"
#include "mvl_defs.h"

/************************************************************************/
/* All the functions below, used for building the ReadJournal response,	*/
/* assume the Journal is modeled as a linked list of journal entries.	*/
/* They use SISCO functions to search the linked list. The user code	*/
/* must use the same linked list functions to add journal entries to	*/
/* the linked list (or remove them from the linked list).		*/
/************************************************************************/

/************************************************************************/
/* Static functions for building the JREAD response.			*/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_time_forward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo);
static MVL_JOURNAL_ENTRY *find_je_start_time_backward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo);

static MVL_JOURNAL_ENTRY *find_je_start_entry (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo);

static MVL_JOURNAL_ENTRY *find_je_stop_forward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je);
static MVL_JOURNAL_ENTRY *find_je_stop_backward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je);

static MVL_JOURNAL_ENTRY *find_je_start_after_forward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je,
                             MVL_JOURNAL_ENTRY *stop_je);
static MVL_JOURNAL_ENTRY *find_je_start_after_backward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je,
                             MVL_JOURNAL_ENTRY *stop_je);

ST_BOOLEAN check_je_list_of_var (JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *je);

/************************************************************************/
/* Global variables for building the JREAD response.			*/
/************************************************************************/
MVL_JOURNAL_ENTRY *je_array [MAX_JREAD_RESP_ENTRIES];	/* array or pointers*/
ST_INT je_array_index;		/* index into "je_array"	*/
ST_INT je_array_num_entries;	/* # of entries in "je_array"	*/
ST_BOOLEAN jread_more_follows;
MVL_JOURNAL_ENTRY *stop_je;	/* journal entry to stop with. 	*/
				/* NOT INCLUDED in response.	*/

/************************************************************************/
/************************************************************************/
ST_RET u_mvl_start_jread (MVL_JOURNAL_CTRL *jCtrl, 
			  JREAD_REQ_INFO *reqInfo, 
			  MVL_JREAD_BUF_CTRL *bufCtrl,
			  ST_VOID **usrHandleOut)
  {
MVL_JOURNAL_ENTRY *je;
MVL_JOURNAL_ENTRY *start_je =jCtrl->entries;	/* First entry that passes*/
						/* "Range Start Spec."	*/
ST_BOOLEAN backwards = SD_FALSE;
ST_INT k;

  /* Init global variables.	*/
  je_array_index = 0;
  je_array_num_entries = 0;
  jread_more_follows = SD_TRUE;		/* Assume "more_follows".	*/

  if (reqInfo->range_start_pres
      &&  reqInfo->start_tag == 0	/* Use Starting time	*/
      &&  reqInfo->start_time.form != MMS_BTOD6)
     {
     printf ("\nERROR: ReadJournal request Starting Time illegal. Must be Btime6.");
     return (SD_FAILURE);
     }
  if (reqInfo->range_stop_pres
      &&  reqInfo->stop_tag == 0	/* Use Stop time	*/
      &&  reqInfo->end_time.form != MMS_BTOD6)
    {
    printf ("\nERROR: ReadJournal request End Time illegal. Must be Btime6.");
    return (SD_FAILURE);
    }
  if (reqInfo->sa_entry_pres
      &&  reqInfo->time_spec.form != MMS_BTOD6)
    {
    printf ("\nERROR: ReadJournal request Time Specification illegal. Must be Btime6.");
    return (SD_FAILURE);
    }

  /* If "Number of Entries" is used and is negative, do reverse order.	*/
  if (reqInfo->range_stop_pres
      &&  reqInfo->stop_tag != 0	/* Use "Number of Entries"	*/
      &&  reqInfo->num_of_entries < 0)	/* Negative			*/
    backwards = SD_TRUE;	/* return entries in reverse order	*/

  /* Process "Range Start Specification"	*/
  if (reqInfo->range_start_pres)
    {
    if (reqInfo->start_tag == 0)	/* Use Starting time	*/
      {
      if (reqInfo->range_stop_pres && reqInfo->stop_tag == 0)
        {		/* Use "Ending Time"	*/
        if (reqInfo->start_time.day > reqInfo->end_time.day  ||
            (reqInfo->start_time.day == reqInfo->end_time.day &&
             reqInfo->start_time.ms > reqInfo->end_time.ms) )
          {		/* Start time > End time	*/
          backwards = SD_TRUE;	/* return entries in reverse order	*/
          }
        }

      if (backwards)
        {
        /* Set "start_je" to the first entry with time <= start time.	*/
        /* Could be NULL if no entry found.				*/
        start_je = find_je_start_time_backward (jCtrl, reqInfo);
        }
      else
        {
        /* Set "start_je" to the first entry with time >= start time.	*/
        /* Could be NULL if no entry found.				*/
        start_je = find_je_start_time_forward (jCtrl, reqInfo);
        }
      if (start_je == NULL)
        return (SD_SUCCESS);	/* None found. Return 0 entries	*/
      }
    else				/* Use "Starting Entry"	*/
      {
      start_je = find_je_start_entry (jCtrl, reqInfo);
      if (start_je == NULL)
        return (SD_FAILURE);	/* If no match, must send Negative resp.*/

      if (reqInfo->range_stop_pres && reqInfo->stop_tag == 0)
        {		/* Use "Ending Time"	*/
        if (start_je->occur_time.day > reqInfo->end_time.day  ||
            (start_je->occur_time.day == reqInfo->end_time.day &&
             start_je->occur_time.ms > reqInfo->end_time.ms) )
          {		/* Entry time > End time	*/
          backwards = SD_TRUE;	/* return entries in reverse order	*/
          }
        }
      }
    }	/* End processing "Range Start Specification".	*/
  else
    start_je = jCtrl->entries;


  /* Process "Range Stop Specification"	*/
  /* Set "stop_je" pointing to first entry past the "stop spec".	*/
  if (backwards)
    {			/* Search BACKWARD thru linked list	*/
    stop_je = find_je_stop_backward (jCtrl, reqInfo, start_je);
    }
  else
    {			/* Search FORWARD thru linked list	*/
    stop_je = find_je_stop_forward (jCtrl, reqInfo, start_je);
    }

  /* Process "Entry to Start After"	*/
  if (reqInfo->sa_entry_pres)
    {		/* "Entry to Start After" specified.	*/
    /* Scan linked list for "Start After Entry" and "Start After Time",	*/
    /* up to "Range Stop", if specified.				*/
    /* Adjust "start_entry" accordingly.				*/
    if (backwards)
      {			/* Search BACKWARD thru linked list	*/
      start_je = find_je_start_after_backward (jCtrl, reqInfo, start_je, stop_je);
      }
    else
      {			/* Search FORWARD thru linked list	*/
      start_je = find_je_start_after_forward (jCtrl, reqInfo, start_je, stop_je);
      }			/* End "Search FORWARD thru linked list"	*/
    }
  else
    ;		/* "Entry to Start After" NOT specified. Do nothing.	*/
  /* End processing of "Entry to Start After"	*/
    
  /* Now find all entries that pass the "List of Variables" filter	*/
  /* and add them to an array of Journal entries to send in response.	*/
  if (backwards)
    {
    for (je = start_je; 
         je != stop_je;
         je = (MVL_JOURNAL_ENTRY *) list_find_prev ((DBL_LNK *) jCtrl->entries, (DBL_LNK *) je))
      {
      if (je_array_num_entries >= MAX_JREAD_RESP_ENTRIES)
        break;				/* Assume still more entries.	*/

      /* If "List of Variables" specified, check if this entry matches.*/
      if (check_je_list_of_var (reqInfo, je))
        je_array[je_array_num_entries++] = je;	/* Matched.	*/
      }	/* end "for"	*/
    }
  else
    {	/* "!backwards"	*/
    for (je = start_je; 
         je != stop_je;
         je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries, je))
      {
      if (je_array_num_entries >= MAX_JREAD_RESP_ENTRIES)
        break;				/* Assume still more entries.	*/

      /* If "List of Variables" specified, check if this entry matches.*/
      if (check_je_list_of_var (reqInfo, je))
        je_array[je_array_num_entries++] = je;	/* Matched.	*/
      }	/* end "for"	*/
    }	/* End "!backwards"	*/
  if (je == stop_je)		/* End of linked list.	*/
    jread_more_follows = SD_FALSE;	/* No more entries	*/

/* We need to tell MVL how many entries and variables we have */
  bufCtrl->numVarInfo = 0;
  bufCtrl->numUsrEntries = je_array_num_entries;
  for (k = 0; k < je_array_num_entries; k++)
    {
    je = je_array [k];
    if (je->entry_form_tag == JE_FORM_DATA && je->ef.data.list_of_var_pres)
      {		/* entry form is 'data' */
      bufCtrl->numVarInfo += je->ef.data.num_of_var;
      }
    }

/* By default, MVL assumes "u_mvl_get_next_jread_entry" returns a	*/
/* pointer (*mvlJeDest) to persistent data.				*/
/* This is a valid assumption for the linked list implementation	*/
/* in this sample code. If you cannot point to persistent data,		*/
/* you must compile the MVL library and this code with			*/
/* MVL_JREAD_*_DYNAMIC defined and adjust the allocation to allow	*/
/* MVL enough space to copy the data.					*/ 

#if defined (MVL_JREAD_ENTRYID_DYNAMIC)
  bufCtrl->entryIdBuf = M_MALLOC (MSMEM_GEN, 1000);
#endif
#if defined (MVL_JREAD_VARTAG_DYNAMIC)
  bufCtrl->varTagBuf = M_MALLOC (MSMEM_GEN, 1000);
#endif
#if defined (MVL_JREAD_ANNOTATION_DYNAMIC)
  bufCtrl->annotationBuf = M_MALLOC (MSMEM_GEN, 1000);
#endif

  return (SD_SUCCESS);
  }

/************************************************************************/
/************************************************************************/
ST_RET u_mvl_get_next_jread_entry (MVL_JOURNAL_CTRL *jCtrl,
				   ST_VOID *usrHandle, 
				   ST_BOOLEAN *moreFollowsOut, 
				   MVL_JOURNAL_ENTRY **mvlJeDest)
  {
  if (je_array_index >= je_array_num_entries)
    return (SD_FAILURE);	/* Should never happen.	*/

  /* If last in "je_array", use "real more_follows value".	*/
  if (je_array_index + 1 == je_array_num_entries)
    *moreFollowsOut = jread_more_follows;
  else
    *moreFollowsOut = SD_TRUE;	/* Not last in array, so always more.	*/

  *mvlJeDest = je_array[je_array_index];
  je_array_index++;		/* Increment array index to next entry.	*/
  return (SD_SUCCESS);
  }

/************************************************************************/

ST_VOID u_mvl_free_jread_entry (MVL_JOURNAL_CTRL *jCtrl, 
				ST_VOID *usrHandle, 
				MVL_JOURNAL_ENTRY *mvlJe)
  {
  }

/************************************************************************/

ST_VOID u_mvl_end_jread (MVL_JOURNAL_CTRL *jCtrl,
			 ST_VOID *usrHandle, 
			 MVL_JREAD_BUF_CTRL *bufCtrl,
			 JREAD_REQ_INFO *reqInfo)
  {

/* Free up buffers allocated in "u_mvl_start_jread".			*/
#if defined (MVL_JREAD_ENTRYID_DYNAMIC)
  M_FREE (MSMEM_GEN, bufCtrl->entryIdBuf);
#endif
#if defined (MVL_JREAD_VARTAG_DYNAMIC)
  M_FREE (MSMEM_GEN, bufCtrl->varTagBuf);
#endif
#if defined (MVL_JREAD_ANNOTATION_DYNAMIC)
  M_FREE (MSMEM_GEN, bufCtrl->annotationBuf);
#endif
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_time_forward (MVL_JOURNAL_CTRL *jCtrl, 
			  JREAD_REQ_INFO *reqInfo)
  {
MVL_JOURNAL_ENTRY *je;

  for (je = jCtrl->entries;
       je != NULL;
       je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries, je))
    {		/* Search entire linked list	*/
    if (je->occur_time.day > reqInfo->start_time.day  ||
        (je->occur_time.day == reqInfo->start_time.day &&
         je->occur_time.ms >= reqInfo->start_time.ms) )
      break;	/* entry time >= start time. Start here.	*/
    }	/* End "for" loop for time spec	*/
  return (je);		/* May be NULL if not found.	*/
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_time_backward (MVL_JOURNAL_CTRL *jCtrl, 
			  JREAD_REQ_INFO *reqInfo)
  {
MVL_JOURNAL_ENTRY *je;

  for (je = (MVL_JOURNAL_ENTRY *) list_find_last ((DBL_LNK *) jCtrl->entries);
       je != NULL;
       je = (MVL_JOURNAL_ENTRY *) list_find_prev ((DBL_LNK *) jCtrl->entries, (DBL_LNK *) je))
    {		/* Search entire linked list	*/
    if (je->occur_time.day < reqInfo->start_time.day  ||
        (je->occur_time.day == reqInfo->start_time.day &&
         je->occur_time.ms <= reqInfo->start_time.ms) )
      break;	/* entry time <= start time. Start here.	*/
    }	/* End "for" loop for time spec	*/
  return (je);		/* May be NULL if not found.		*/
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_entry (MVL_JOURNAL_CTRL *jCtrl, 
			  JREAD_REQ_INFO *reqInfo)
  {
MVL_JOURNAL_ENTRY *je;
  for (je = jCtrl->entries;
       je != NULL;
       je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries, je))
    {
    if (je->entry_id_len == reqInfo->start_entry_len &&
        !memcmp (je->entry_id, reqInfo->start_entry, je->entry_id_len))
      return (je);	/* entry id == Starting Entry. Start here.	*/
    }	/* End "for" loop for "Starting Entry"	*/
  return (NULL);
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_stop_forward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je)
  {
MVL_JOURNAL_ENTRY *je;
MVL_JOURNAL_ENTRY *stop_je;
ST_INT num_entries;


  if (reqInfo->range_stop_pres)
    {
    for (je = start_je, num_entries = 0; 
         je != NULL;
         je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries, je),
         num_entries++)
      {
      if (reqInfo->stop_tag == 0)
        {		/* Use "Ending Time"	*/
        if (je->occur_time.day > reqInfo->end_time.day  ||
            (je->occur_time.day == reqInfo->end_time.day &&
             je->occur_time.ms > reqInfo->end_time.ms) )
          {		/* Entry time > End time	*/
          break;	/* Found it. Done.	*/
          }
        }
      else
        {		/* Use "Number of entries"	*/
        if (num_entries >= reqInfo->num_of_entries)
          break;	/* Found it. Done.	*/
        }
      }	/* end "for"	*/
    stop_je = je;	/* May be NULL if not found.	*/
    }
  else
    stop_je = NULL;	/* No stop spec. Set to NULL (i.e. end of list)	*/

  return (stop_je);
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_stop_backward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je)
  {
MVL_JOURNAL_ENTRY *je;
MVL_JOURNAL_ENTRY *stop_je;
ST_INT num_entries;

  if (reqInfo->range_stop_pres)
    {
    for (je = start_je, num_entries = 0; 
         je != NULL;
         je = (MVL_JOURNAL_ENTRY *) list_find_prev ((DBL_LNK *) jCtrl->entries, (DBL_LNK *) je),
         num_entries++)
      {
      if (reqInfo->stop_tag == 0)
        {		/* Use "Ending Time"	*/
        if (je->occur_time.day < reqInfo->end_time.day  ||
            (je->occur_time.day == reqInfo->end_time.day &&
             je->occur_time.ms < reqInfo->end_time.ms) )
          {		/* Entry time < End time	*/
          break;	/* Found it. Done.	*/
          }
        }
      else
        {	/* Use "Number of entries" ("0 -" converts neg to pos)	*/
        if (num_entries >= (0 - reqInfo->num_of_entries) )
          break;	/* Found it. Done.	*/
        }
      }	/* end "for"	*/
    stop_je = je;	/* May be NULL if not found.	*/
    }
  else
    stop_je = NULL;	/* No stop spec. Set to NULL (i.e. end of list)	*/

  return (stop_je);
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_after_forward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je,
                             MVL_JOURNAL_ENTRY *stop_je)
  {
MVL_JOURNAL_ENTRY *je;
MVL_JOURNAL_ENTRY *start_after_entry_je=NULL;	/* First entry that passes*/
						/* "Start After Entry Spec."*/
MVL_JOURNAL_ENTRY *start_after_time_je=NULL;	/* First entry that passes*/
						/* "Start After Time Spec."*/

  /* The variables "start_after_entry_je" and/or "start_after_time_je"*/
  /* will be set to non-NULL values if they are found.		*/
  /* If one of them is found, adjust "start_entry" accordingly.	*/
  for (je = start_je; 
       je != stop_je;
       je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries, je))
    {
    /* Check for matching "entry_spec"	*/
    if (je->entry_id_len == reqInfo->entry_spec_len &&
        !memcmp (je->entry_id, reqInfo->entry_spec, je->entry_id_len))
      {	/* entry spec matches	*/
      start_after_entry_je = je;
      break;	/* Done checking.	*/
      }

    /* If haven't found matching "entry_spec" yet, check "time_spec".	*/
    if (start_after_time_je == NULL)
      {				/* "time_spec" match not found yet.	*/
      if (je->occur_time.day > reqInfo->time_spec.day  ||
          (je->occur_time.day == reqInfo->time_spec.day &&
           je->occur_time.ms > reqInfo->time_spec.ms) )
        {	/* entry time > time spec.	*/
        /* Save this but keep checking for matching "entry_spec".	*/
        start_after_time_je = je;	/* DO NOT "break"		*/
        }
      }
    }	/* end "for"	*/

  /* If found match on Start After Entry, start with NEXT entry.	*/
  /* If only found match on Start After Time, start with THAT entry.*/
  if (start_after_entry_je)
    start_je = (MVL_JOURNAL_ENTRY *) list_get_next (jCtrl->entries,
               start_after_entry_je);
  else if (start_after_time_je)
    start_je = start_after_time_je;
  else
    start_je = NULL;	/* Didn't find either. Return 0 entries.*/
  return (start_je);
  }

/************************************************************************/
/************************************************************************/
static MVL_JOURNAL_ENTRY *find_je_start_after_backward (MVL_JOURNAL_CTRL *jCtrl, 
			     JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *start_je,
                             MVL_JOURNAL_ENTRY *stop_je)
  {
MVL_JOURNAL_ENTRY *je;
MVL_JOURNAL_ENTRY *start_after_entry_je=NULL;	/* First entry that passes*/
						/* "Start After Entry Spec."*/
MVL_JOURNAL_ENTRY *start_after_time_je=NULL;	/* First entry that passes*/
						/* "Start After Time Spec."*/

  /* The variables "start_after_entry_je" and/or "start_after_time_je"	*/
  /* will be set to non-NULL values if they are found.			*/
  /* If one of them is found, adjust "start_entry" accordingly.		*/
  for (je = start_je; 
       je != stop_je;
       je = (MVL_JOURNAL_ENTRY *) list_find_prev ((DBL_LNK *) jCtrl->entries, (DBL_LNK *) je))
    {
    /* Check for matching "entry_spec"	*/
    if (je->entry_id_len == reqInfo->entry_spec_len &&
        !memcmp (je->entry_id, reqInfo->entry_spec, je->entry_id_len))
      {	/* entry spec matches	*/
      start_after_entry_je = je;
      break;	/* Done checking.	*/
      }

    /* If haven't found matching "entry_spec" yet, check "time_spec".	*/
    if (start_after_time_je == NULL)
      {				/* "time_spec" match not found yet.	*/
      if (je->occur_time.day < reqInfo->time_spec.day  ||
          (je->occur_time.day == reqInfo->time_spec.day &&
           je->occur_time.ms < reqInfo->time_spec.ms) )
        {	/* entry time < time spec.	*/
        /* Save this but keep checking for matching "entry_spec".	*/
        start_after_time_je = je;	/* DO NOT "break"		*/
        }
      }
    }	/* end "for"	*/

  /* If found match on Start After Entry, start with NEXT entry.	*/
  /* If only found match on Start After Time, start with THAT entry.*/
  if (start_after_entry_je)
    start_je = (MVL_JOURNAL_ENTRY *) list_find_prev ((DBL_LNK *) jCtrl->entries,
               (DBL_LNK *) start_after_entry_je);
  else if (start_after_time_je)
    start_je = start_after_time_je;
  else
    start_je = NULL;	/* Didn't find either. Return 0 entries.*/
  return (start_je);
  }

/************************************************************************/
/************************************************************************/
ST_BOOLEAN check_je_list_of_var (JREAD_REQ_INFO *reqInfo, 
                             MVL_JOURNAL_ENTRY *je)
  {
ST_BOOLEAN retcode = SD_FALSE;	/* No match.	*/
ST_INT j, k;
ST_CHAR **list_of_var;

  if (reqInfo->list_of_var_pres)
    {
    list_of_var = (ST_CHAR **) (reqInfo + 1);
    
    if (je->entry_form_tag == JE_FORM_DATA
        && je->ef.data.list_of_var_pres)
      {
      for (j = 0; j < reqInfo->num_of_var;  j++)
        {
        for (k = 0; k < je->ef.data.num_of_var; k++)
          {
          if (!strcmp (je->ef.data.list_of_var[k].var_tag, list_of_var [j]))
            retcode = SD_TRUE;	/* Matched.	*/
          }	/* end "for" loop	*/
        }	/* end "for" loop	*/
      }
    }	/* End "if (reqInfo->list_of_var_pres)"	*/
  else
    {	/* No "List of Variables" to check. This one must be OK.*/
    retcode = SD_TRUE;		/* Just as good as a match.	*/
    }
  return (retcode);
  }

