/* -*- mode: C -*- */
/* --------------------------------------------------------------------------
   libconfig - A library for processing structured configuration files
   Copyright (C) 2005-2020  Mark A Lindner

   This file is part of libconfig.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   This library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, see
   <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------------
*/

%option nounistd
%option never-interactive
%option reentrant
%option noyywrap
%option yylineno
%option nounput
%option bison-bridge
%option header-file="scanner.h"
%option outfile="lex.yy.c"
%option extra-type="struct scan_context *"

%{

#ifdef _MSC_VER
#pragma warning (disable: 4996)
#endif

#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>

#include "parsectx.h"
#include "scanctx.h"
#include "grammar.h"
#include "wincompat.h"
#include "util.h"

#define YY_NO_INPUT // Suppress generation of useless input() function

%}

true              [Tt][Rr][Uu][Ee]
false             [Ff][Aa][Ll][Ss][Ee]
name              [A-Za-z\*][-A-Za-z0-9_\*]*
integer           [-+]?[0-9]+
integer64         [-+]?[0-9]+L(L)?
hex               0[Xx][0-9A-Fa-f]+
hex64             0[Xx][0-9A-Fa-f]+L(L)?
hexchar           \\[Xx][0-9A-Fa-f]{2}
float             ([-+]?([0-9]*)?\.[0-9]*([eE][-+]?[0-9]+)?)|([-+]?([0-9]+)(\.[0-9]*)?[eE][-+]?[0-9]+)
include_open ^[ \t]*@include[ \t]+\"

%x SINGLE_LINE_COMMENT MULTI_LINE_COMMENT STRING INCLUDE

%%

(#|\/\/)                     { BEGIN SINGLE_LINE_COMMENT; }
<SINGLE_LINE_COMMENT>\n      { BEGIN INITIAL; }
<SINGLE_LINE_COMMENT>.       { /* ignore */ }

\/\*                         { BEGIN MULTI_LINE_COMMENT; }
<MULTI_LINE_COMMENT>\*\/     { BEGIN INITIAL; }
<MULTI_LINE_COMMENT>.        { /* ignore */ }
<MULTI_LINE_COMMENT>\n       { /* ignore */ }

\"                { BEGIN STRING; }
<STRING>[^\"\\]+  { libconfig_scanctx_append_string(yyextra, yytext); }
<STRING>\\n       { libconfig_scanctx_append_char(yyextra, '\n'); }
<STRING>\\r       { libconfig_scanctx_append_char(yyextra, '\r'); }
<STRING>\\t       { libconfig_scanctx_append_char(yyextra, '\t'); }
<STRING>\\f       { libconfig_scanctx_append_char(yyextra, '\f'); }
<STRING>\\\\      { libconfig_scanctx_append_char(yyextra, '\\'); }
<STRING>\\\"      { libconfig_scanctx_append_char(yyextra, '\"'); }
<STRING>{hexchar} {
                    char c = (char)(strtol(yytext + 2, NULL, 16) & 0xFF);
                    libconfig_scanctx_append_char(yyextra, c);
                  }
<STRING>\\        { libconfig_scanctx_append_char(yyextra, '\\'); }
<STRING>\"        {
                    yylval->sval = libconfig_scanctx_take_string(yyextra);
                    BEGIN INITIAL;
                    return(TOK_STRING);
                  }

{include_open}    { BEGIN INCLUDE; }
<INCLUDE>[^\"\\]+ { libconfig_scanctx_append_string(yyextra, yytext); }
<INCLUDE>\\\\     { libconfig_scanctx_append_char(yyextra, '\\'); }
<INCLUDE>\\\"     { libconfig_scanctx_append_char(yyextra, '\"'); }
<INCLUDE>\"       {
  const char *error = NULL;
  const char *path = libconfig_scanctx_take_string(yyextra);
  FILE *fp = libconfig_scanctx_push_include(yyextra, (void *)YY_CURRENT_BUFFER,
                                            path, &error);
  __delete(path);

  if(fp)
  {
    yyin = fp;
    yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
                        yyscanner);
  }
  else if(error)
  {
    yyextra->config->error_text = error;
    yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra);
    yyextra->config->error_line = libconfig_yyget_lineno(yyscanner);
    return TOK_ERROR;
  }
  BEGIN INITIAL;
}

\n|\r|\f          { /* ignore */ }
[ \t]+            { /* ignore */ }

\=|\:             { return(TOK_EQUALS); }
,                 { return(TOK_COMMA); }
\{                { return(TOK_GROUP_START); }
\}                { return(TOK_GROUP_END); }
{true}            { yylval->ival = 1; return(TOK_BOOLEAN); }
{false}           { yylval->ival = 0; return(TOK_BOOLEAN); }
{name}            { yylval->sval = yytext; return(TOK_NAME); }
{float}           { yylval->fval = atof(yytext); return(TOK_FLOAT); }
{integer}         {
                    int ok;
                    long long llval = libconfig_parse_integer(yytext, &ok);
                    if(!ok)
                      return(TOK_ERROR);

                    if((llval < INT_MIN) || (llval > INT_MAX))
                    {
                      yylval->llval = llval;
                      return(TOK_INTEGER64);
                    }
                    else
                    {
                      yylval->ival = (int)llval;
                      return(TOK_INTEGER);
                    }
                  }
{integer64}       { yylval->llval = atoll(yytext); return(TOK_INTEGER64); }
{hex}             {
                    yylval->ival = strtoul(yytext, NULL, 16);
                    return(TOK_HEX);
                  }
{hex64}           {
                    yylval->llval = libconfig_parse_hex64(yytext);
                    return(TOK_HEX64);
                  }
\[                { return(TOK_ARRAY_START); }
\]                { return(TOK_ARRAY_END); }
\(                { return(TOK_LIST_START); }
\)                { return(TOK_LIST_END); }
;                 { return(TOK_SEMICOLON); }
.                 { return(TOK_GARBAGE); }

<<EOF>>           {
  const char *error = NULL;
  FILE *fp;

  fp = libconfig_scanctx_next_include_file(yyextra, &error);
  if(fp)
  {
    yyin = fp;
    yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
    yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
                        yyscanner);
  }
  else if(error)
  {
    yyextra->config->error_text = error;
    yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra);
    yyextra->config->error_line = libconfig_yyget_lineno(yyscanner);
    return TOK_ERROR;
  }
  else
  {
    /* No more files in the current include list. */
    YY_BUFFER_STATE buf = (YY_BUFFER_STATE)libconfig_scanctx_pop_include(yyextra);
    if(buf)
    {
      yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
      yy_switch_to_buffer(buf, yyscanner);
    }
    else
      yyterminate();
  }
}
