/*******************************************************************\

Module: printf Formatting

Author: Daniel Kroening, kroening@kroening.com

\*******************************************************************/

#include <assert.h>

#include <ansi-c/c_types.h>

#include "printf_formatter.h"

/*******************************************************************\

Function: printf_formattert::operator()

  Inputs:

 Outputs:

 Purpose:

\*******************************************************************/

void printf_formattert::operator()(const exprt::operandst &operands)
{
  const exprt &format=operands[0];
  
  if(format.id()=="address_of" &&
     format.operands().size()==1 &&
     format.op0().id()=="index" &&
     format.op0().operands().size()==2 &&
     format.op0().op0().id()=="string-constant" &&
     format.op0().op1().is_zero())
  {
    const exprt &fmt_str=format.op0().op0();
    const std::string &fmt=fmt_str.get_string("value");
    
    text="";
    mode=TEXT;
    op_nr=1;

    text.reserve(fmt.size());

    for(unsigned p=0; p<fmt.size(); p++)
      process_char(fmt[p]);

    flush_text();
  }
  else
  {
    std::cout << "XXX: " << format.pretty() << std::endl;
    // ignore for now
  }

}

/*******************************************************************\

Function: printf_formattert::flush_text

  Inputs:

 Outputs:

 Purpose:

\*******************************************************************/

void printf_formattert::flush_text()
{
  if(text!="")
  {
    exprt text_expr("string-constant", typet("array"));
    text_expr.type().subtype()=char_type();
    text_expr.type().set("size", text.size()+1);

    text_expr.set("value", text);
    dest.push_back(text_expr);
    text="";
  }
}

/*******************************************************************\

Function: printf_formattert::process_char

  Inputs:

 Outputs:

 Purpose:

\*******************************************************************/

void printf_formattert::process_char(char ch)
{
  switch(mode)
  {
  case TEXT:
    if(ch=='%')
      mode=FORMAT;
    else
      text+=ch;
    break;

  case FORMAT:
    flush_text();

    switch(ch)
    {
    case '%':
      text+=ch;
      break;

    case 's':
    case 'S':
      {
        
      }
      break;

    default:
      text+='%';
      text+=ch;
    }

    mode=TEXT;
    break;

  default:
    assert(false);
  }
}
