/* token.C
 * John Viega
 *
 * Jul 28, 1999 (with some mods in Jan 2000)
 */

#include "token.H"

TokenContainer::TokenContainer() 
{
  increment = DEFAULT_TOKEN_CONTAINER_UNIT;
  list = new Token*[increment];
  if(!list)
    OutOfMemory();
  current_size = 0;
  current_capacity = increment;
}

TokenContainer::TokenContainer(int incr)
{
  increment = incr;
  list = new Token*[increment];
  if(!list)
    OutOfMemory();
  current_size = 0;
  current_capacity = increment;
}

void TokenContainer::Add(Token *t)
{
  if((t->GetTokenType() == STRING) && current_size && 
     (list[current_size-1]->GetTokenType() == STRING))
    {
      int newlen = ((StringTok *)t)->GetContentLength() +
	    ((StringTok *)list[current_size-1])->GetContentLength() + 1;
      char *buf = new char[newlen];
      /* ITS4: ignore sprintf */
      sprintf(buf, "%s%s", ((StringTok *)list[current_size-1])->GetContents(),
	      ((StringTok *)t)->GetContents());
      delete t;
      t = list[current_size-1];
      // TODO: keep track of the token's EXTENT when it spans lines.
      list[current_size-1] = new StringTok(buf, newlen-1, t->GetLineNo());
      delete t;
      return;
    }
  list[current_size++] = t;
  if(current_size == current_capacity) 
    {
      Resize();
    }
#ifdef ITS_DEBUG
  // For debugging the token stream.
  fprintf(stderr, "%s\n", t->GetRepr());
#endif
}

Token* TokenContainer::GetToken(int i)
{
  if(i >= current_size || i < 0) return 0;
  return list[i];
}

void TokenContainer::Resize()
{
  Token **tmp = new Token*[current_capacity+increment];
  if(!tmp)
    OutOfMemory();
  for(int i=0;i<current_capacity;i++)
    {
      tmp[i] = list[i];
    }
  current_capacity = current_capacity + increment;
  delete[] list;
  list = tmp;
}
