# include "basic.h"
# define D_NLINES 100
static char prompt[] = ">> ";

int run_while (int argc, char **argv) {

  int ThisList, depth, i, done, status, NLINES, j;
  char *input, *val;
  int logic, size;
  Macro loop;

  if (argc != 2) {
    fprintf (stderr, "USAGE: while (condition)\n");
    return (FALSE);
  }

  val = dvomath (1, &argv[1], &size, 0);
  if (val == NULL) return (FALSE);
  logic = atof (val); /* warning: round-off error is a danger */
  
  NLINES = D_NLINES;
  ALLOCATE (loop.line, char *, NLINES);

  /* read in loop */
  depth = 0;
  ThisList = Nlists;
  for (i = 0, done = FALSE; !done; ) {

    /* get the next line (from correct place) */
    if (ThisList == 0) 
      input = readline (prompt);
    else 
      input = get_next_listentry (ThisList);
    stripwhite (input);

    /* check for end-of-data syntax error */
    if (input == (char *) NULL) {
      if (ThisList == 0)  {
	fprintf (stderr, "end 'while' loop with 'END'\n");
	continue;
      } else {
	fprintf (stderr, "misbalanced 'while' loop\n");
	for (j = 0; j < loop.Nlines; j++) {
	  free (loop.line[j]);
	}
	free (loop.line);
	return (FALSE);
      }	
    }

    /* test for new macro (or other list, in the future?) */
    if (is_list (input)) depth ++;

    /* test for end of nested list -- if not nested, END refers to this macro */
    if (!strncasecmp (input, "END", 3)) {
      depth --;
      if (depth < 0) break;
    }

    /* if line has data, add to loop list */
    if (*input) { 
      loop.line[i] = input;
      i++;
      if (i == NLINES - 1) {
	NLINES += D_NLINES;
	REALLOCATE (loop.line, char *, NLINES);
      }
    }
  }

  /* cleanup loop data */
  free (input);
  loop.Nlines = i;
  REALLOCATE (loop.line, char *, MAX (loop.Nlines, 1));

  /* execute for loop */
  do { 
    loop_continue = loop_break = FALSE;
    status = exec_loop (&loop);
    if (loop_break) break;
    if (loop_continue) continue;

    val = dvomath (1, &argv[1], &size, 0);
    if (val == NULL) return (FALSE);
    logic = atof (val); /* warning: round-off error is a danger */
  } while (logic && !interrupt);
  loop_continue = loop_break = FALSE;
  if (auto_break && !status) loop_break = TRUE;

  /* cleanup list */
  for (j = 0; j < loop.Nlines; j++) {
    free (loop.line[j]);
  }
  free (loop.line);
  if (loop_break) return (FALSE);
  return (TRUE);
}
