/**********************************************************************
 * ti library's routine for reading nodes of menu
 *
 * $Author: brlewis $
 * $Source: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/rdmenu.c,v $
 * $Header: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/rdmenu.c,v 0.4 92/07/09 17:07:28 brlewis Exp $
 *
 * Copyright 1992 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/

#include <mit-copyright.h>

#ifndef lint
static char rcsid_ti_rdmenu_c[] = "$Header: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/rdmenu.c,v 0.4 92/07/09 17:07:28 brlewis Exp $";
#endif /* lint */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ti/memory.h>
#include <ti/ti.h>

/**********************************************************************
 * ti_rdmenu(ti_menu hmenu, ti_node_HH FAR *lpahnode, int *countp;)
 *	puts correct nodes in lpahnode
 *        (long pointer to an array of handles to nodes)
 *	puts node count in countp;
 *
 * - returns error code
 **********************************************************************/

/* jms 7/24/92 -- windows-izing begun */

long
ti_rdmenu(hmenu, lpahnode, countp)
     ti_menu_H hmenu;
     ti_node_HH FAR *lpahnode;
     int *countp;
{
  long code;
  LPSTR buf;
  int bufsize = BUFSIZ;
  char trashcan[BUFSIZ];
  register char *str1;
  int array_size=0;

  ti_menu_LP lpmenu = NULL;
  ti_node_LP lpnode = NULL;
  ti_node_H  hnode = NULL;
  ti_node_LPH lphnode = NULL;

  lpmenu = (ti_menu_LP)TI_DEREFERENCE(hmenu);

  /* allocate buffer to receive menu */
  TI_MEM(buf=NewArray(char, bufsize))

  /* zero *lpahnode so we know not to free it */
  *lpahnode = NULL;

  /* send query and receive reply */
  code=_ti_talk(lpmenu->tp, lpmenu->query, strlen(lpmenu->query),
		buf, BUFSIZ);

  /* enlarge buf as necessary to hold server reply */
  while (code == TI_ERR_TOOLONG)
    {
      if (!(buf = BiggerArray(char, buf, (bufsize += BUFSIZ))))
	{
	  /* flush the rest of the server reply */
	  while(code == TI_ERR_TOOLONG)
	    code=_ti_recvmsg(lpmenu->tp, trashcan, BUFSIZ);
	  CLEANUP_AND_RETURN((long) ENOMEM)
	}
      code = _ti_recvmsg(lpmenu->tp, buf+bufsize-BUFSIZ, BUFSIZ);
    }
  if (code) goto CLEANUP;

  /* initialize array */
  if (lpmenu->title) array_size = 1;
  TI_MEM(*lpahnode=NewArray(ti_node_H, atoi(buf)+array_size))
  lphnode = (ti_node_LPH)TI_DEREFERENCE(*lpahnode);

  /* insert initial title */
  if (lpmenu->title)
    {
      if (code=ti_newnode(lphnode)) goto CLEANUP;
      ti_settitle(lphnode[0], lpmenu->title);
    }

  str1 = index(buf, '\n')+1;
  while (*str1)
    {
      if (code=ti_newnode(&(lphnode[array_size]))) goto CLEANUP;
      array_size++;
      if (code=_ti_str2nd(lpmenu->tp, str1, lphnode[array_size-1]))
	goto CLEANUP;
      /* skip ahead to next line */
      while(*str1 && *str1 != '\r' && *str1 != '\n') str1++;
      if (*str1) while(*str1 == '\r' || *str1 == '\n') str1++;
    }
/* !!!!! */
  if (!(*np=BiggerArray(ti_node *, *np, array_size+1)))
    {
      CLEANUP_AND_RETURN((long) ENOMEM)
    }

  /* success!  null-terminate array */
  (*np)[array_size] = NULL;
  if (countp) *countp = array_size;
  Delete(buf);
  return(0L);

CLEANUP:
  /* failure */
  Delete(buf);
  if (*lpahnode) ti_freenodes(*lpahnode);
  TI_REMOVE_DEREFERENCE(hmenu, lpmenu);
  return(code);
}
