/* lexer.c - The scripting lexer.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>

#include <grub/parser.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/script_sh.h>
#include <grub/i18n.h>

#define yytext_ptr char *
#include "grub_script.tab.h"
#include "grub_script.yy.h"

void
grub_script_lexer_ref (struct grub_lexer_param *state)
{
  state->refs++;
}

void
grub_script_lexer_deref (struct grub_lexer_param *state)
{
  state->refs--;
}

/* Start recording all characters passing through the lexer.  */
unsigned
grub_script_lexer_record_start (struct grub_parser_param *parser)
{
  struct grub_lexer_param *lexer = parser->lexerstate;

  lexer->record++;
  if (lexer->recording)
    return lexer->recordpos;

  lexer->recordpos = 0;
  lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE;
  lexer->recording = grub_malloc (lexer->recordlen);
  if (!lexer->recording)
    {
      grub_script_yyerror (parser, 0);
      lexer->recordlen = 0;
    }
  return lexer->recordpos;
}

char *
grub_script_lexer_record_stop (struct grub_parser_param *parser, unsigned offset)
{
  int count;
  char *result;
  struct grub_lexer_param *lexer = parser->lexerstate;

  if (!lexer->record)
    return 0;

  lexer->record--;
  if (!lexer->recording)
    return 0;

  count = lexer->recordpos - offset;
  result = grub_script_malloc (parser, count + 1);
  if (result) {
    grub_strncpy (result, lexer->recording + offset, count);
    result[count] = '\0';
  }

  if (lexer->record == 0)
    {
      grub_free (lexer->recording);
      lexer->recording = 0;
      lexer->recordlen = 0;
      lexer->recordpos = 0;
    }
  return result;
}

/* Record STR if input recording is enabled.  */
void
grub_script_lexer_record (struct grub_parser_param *parser, char *str)
{
  int len;
  char *old;
  struct grub_lexer_param *lexer = parser->lexerstate;

  if (!lexer->record || !lexer->recording)
    return;

  len = grub_strlen (str);
  if (lexer->recordpos + len + 1 > lexer->recordlen)
    {
      old = lexer->recording;
      if (lexer->recordlen < len)
	lexer->recordlen = len;
      lexer->recordlen *= 2;
      lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
      if (!lexer->recording)
	{
	  grub_free (old);
	  lexer->recordpos = 0;
	  lexer->recordlen = 0;
	  grub_script_yyerror (parser, 0);
	  return;
	}
    }
  grub_strcpy (lexer->recording + lexer->recordpos, str);
  lexer->recordpos += len;
}

/* Read next line of input if necessary, and set yyscanner buffers.  */
int
grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
			  const char *input)
{
  grub_size_t len = 0;
  char *p = 0;
  char *line = 0;
  YY_BUFFER_STATE buffer;
  struct grub_lexer_param *lexerstate = parserstate->lexerstate;

  if (! lexerstate->refs && ! lexerstate->prefix && ! input)
    return 1;

  if (! lexerstate->getline && ! input)
    {
      grub_script_yyerror (parserstate, N_("unexpected end of file"));
      return 1;
    }

  line = 0;
  if (! input)
    lexerstate->getline (&line, 1, lexerstate->getline_data);
  else
    line = grub_strdup (input);

  if (! line)
    {
      grub_script_yyerror (parserstate, N_("out of memory"));
      return 1;
    }

  len = grub_strlen (line);

  /* Ensure '\n' at the end.  */
  if (line[0] == '\0')
    {
      grub_free (line);
      line = grub_strdup ("\n");
      len = 1;
    }
  else if (len && line[len - 1] != '\n')
    {
      p = grub_realloc (line, len + 2);
      if (p)
	{
	  p[len++] = '\n';
	  p[len] = '\0';
	}
      line = p;
    }

  if (! line)
    {
      grub_script_yyerror (parserstate, N_("out of memory"));
      return 1;
    }

  /* Prepend any left over unput-text.  */
  if (lexerstate->prefix)
    {
      int plen = grub_strlen (lexerstate->prefix);

      p = grub_malloc (len + plen + 1);
      if (! p)
	{
	  grub_free (line);
	  return 1;
	}
      grub_strcpy (p, lexerstate->prefix);
      lexerstate->prefix = 0;

      grub_strcpy (p + plen, line);
      grub_free (line);

      line = p;
      len = len + plen;
    }

  buffer = yy_scan_string (line, lexerstate->yyscanner);
  grub_free (line);

  if (! buffer)
    {
      grub_script_yyerror (parserstate, 0);
      return 1;
    }
  return 0;
}

struct grub_lexer_param *
grub_script_lexer_init (struct grub_parser_param *parser, char *script,
			grub_reader_getline_t arg_getline, void *getline_data)
{
  struct grub_lexer_param *lexerstate;

  lexerstate = grub_zalloc (sizeof (*lexerstate));
  if (!lexerstate)
    return 0;

  lexerstate->size = GRUB_LEXER_INITIAL_TEXT_SIZE;
  lexerstate->text = grub_malloc (lexerstate->size);
  if (!lexerstate->text)
    {
      grub_free (lexerstate);
      return 0;
    }

  lexerstate->getline = arg_getline;
  lexerstate->getline_data = getline_data;
  /* The other elements of lexerstate are all zeros already.  */

  if (yylex_init (&lexerstate->yyscanner))
    {
      grub_free (lexerstate->text);
      grub_free (lexerstate);
      return 0;
    }

  yyset_extra (parser, lexerstate->yyscanner);
  parser->lexerstate = lexerstate;

  if (grub_script_lexer_yywrap (parser, script ?: "\n"))
    {
      parser->lexerstate = 0;
      yylex_destroy (lexerstate->yyscanner);
      grub_free (lexerstate->text);
      grub_free (lexerstate);
      return 0;
    }

  return lexerstate;
}

void
grub_script_lexer_fini (struct grub_lexer_param *lexerstate)
{
  if (!lexerstate)
    return;

  yylex_destroy (lexerstate->yyscanner);

  grub_free (lexerstate->recording);
  grub_free (lexerstate->text);
  grub_free (lexerstate);
}

int
grub_script_yylex (union YYSTYPE *value,
		   struct grub_parser_param *parserstate)
{
  char *str;
  int token;
  grub_script_arg_type_t type;
  struct grub_lexer_param *lexerstate = parserstate->lexerstate;

  value->arg = 0;
  if (parserstate->err)
    return GRUB_PARSER_TOKEN_BAD;

  if (lexerstate->eof)
    return GRUB_PARSER_TOKEN_EOF;

  /* 
   * Words with environment variables, like foo${bar}baz needs
   * multiple tokens to be merged into a single grub_script_arg.  We
   * use two variables to achieve this: lexerstate->merge_start and
   * lexerstate->merge_end
   */

  lexerstate->merge_start = 0;
  lexerstate->merge_end = 0;
  do
    {
      /* Empty lexerstate->text.  */
      lexerstate->used = 1;
      lexerstate->text[0] = '\0';

      token = yylex (value, lexerstate->yyscanner);
      if (token == GRUB_PARSER_TOKEN_BAD)
	break;

      /* Merging feature uses lexerstate->text instead of yytext.  */
      if (lexerstate->merge_start)
	{
	  str = lexerstate->text;
	  type = lexerstate->type;
	}
      else
	{
	  str = yyget_text (lexerstate->yyscanner);
	  type = GRUB_SCRIPT_ARG_TYPE_TEXT;
	}
      grub_dprintf("lexer", "token %u text [%s]\n", token, str);

      value->arg = grub_script_arg_add (parserstate, value->arg, type, str);
    }
  while (lexerstate->merge_start && !lexerstate->merge_end);

  if (!value->arg || parserstate->err)
    return GRUB_PARSER_TOKEN_BAD;

  return token;
}

void
grub_script_yyerror (struct grub_parser_param *state, char const *err)
{
  if (err)
    grub_error (GRUB_ERR_INVALID_COMMAND, err);

  grub_print_error ();
  state->err++;
}
