# include "opihi.h"

char *expand_vars (char *line) {

  char *L, *N, *V0, *V1, *Val, *newline, *c, found;
  int done, MacroDepth;

  if (line == NULL) return (NULL);
  MacroDepth = GetMacroDepth ();

  found = FALSE;
  ALLOCATE (newline, char, 1024);  /* WARNING: this limits the length of the input line */

  /* look for form $a$b..$n and expand only the last ones */
  for (L = line, N = newline; *L != 0; N++, L++) {  /* loop until end of line */
    for (done = FALSE; !done;) {
      if (*L == 0) done = TRUE;
      if (*L == '$') {
	V1 = aftervar(L);
	if ((V1 != NULL) && (*V1 != '$')) done = TRUE;
	if (V1 == NULL) done = TRUE;
      }
      if (!done) { 
	*N = *L;
	 L++; 
	 N++;
      }
    }

    if (*L == 0) break;

    V1 = aftervar (L);           /* V1 points to the first non-whitespace after the variable */
    V0 = thisvar (L);            /* V0 points to the name of the var */
    /* note: V1 points to a fraction of L, it does not need to be freed */

    /* no variable name */
    if (V0 == NULL) {
      *N = *L;
      continue;
    }

    /* variable assignment (skip these variables) */
    if ((L == line) && (V1 != NULL)) {
      if ((*V1 == '=') || !strcmp (V1, "++") || !strcmp (V1, "--")) {
	*N = *L;
	continue;
      }
    }

    found = TRUE;
    for (c = V0; isdigit(*c); c++); /* test if this is a macro argument variable (ie, $1.2) */
    if (*c == 0) {  /* all digit var == macro parameter */
      if (!MacroDepth) {
	fprintf (stderr, "not in a macro\n");
	goto error;
      } else { /* if we are executing a macro, attach the list depth to the front, pass on down the line */
	ALLOCATE (c, char, 1024);
	sprintf (c, "%d.%s", MacroDepth, V0);
	free (V0);
	V0 = c;
      }
    }

    Val = get_variable_ptr (V0);
    if (Val == NULL) {   /* var was not found! */
      fprintf (stderr, "variable %s not found\n", V0);
      goto error;
    }
    for (; *Val != 0; N++, Val++)  {
      *N = *Val; /* place the value of the variable in the newline */
    }

    for (N--,L++; ISVAR(*L); L++);
    L--;

    if (V0 != NULL) free (V0);
  }

  *N = 0;
  free (line);
  REALLOCATE (newline, char, strlen (newline) + 1);
  if (found) { /* try again for new variables */
    newline = expand_vars (newline);
  }
  return (newline);

error:
  free (line);
  free (V0);
  free (newline);
  return (NULL);
}


  /************************
    we go through the line looking for the dollar signs ($) marking the 
    variables.  We don't expand a variable if it is the first thing on the line 
    AND it is followed by an equals sign.  
    that is, don't expand if:
    V0 = NULL ($ is last non-blank char on line -- no variable) or
    V1[0] is = (assignment of variable value), AND L == line (ie, at beginning of line)
    *************************/

