%{
/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <assert.h>
#include <ctype.h>
#include <elf.h>
#include <error.h>
#include <inttypes.h>
#include <libintl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include <system.h>
#include <ld.h>
#include "ldscript.h"

/* We sure use no threads to read the stream, so use the _unlocked
   variants of the functions.  */
#undef getc
#define getc(s) getc_unlocked (s)
#undef ferror
#define ferror(s) ferror_unlocked (s)
#undef fread
#define fread(b, m, n, s) fread_unlocked (b, m, n, s)
#undef fwrite
#define fwrite(b, m, n, s) fwrite_unlocked (b, m, n, s)

/* Defined in ld.c.  */
extern int ld_scan_version_script;

#define MAX_PREPDEPTH 20
static enum prepstate
{
  prep_normal,
  skip_if,
  skip_to_endif
} prepstate[MAX_PREPDEPTH];
static int prepdepth;

static void eat_comment (void);
static void eat_to_eol (bool empty);
static int attrib_convert (int c);
static void push_state (enum prepstate);
static int pop_state (void);
static int handle_ifdef (void);
static void invalid_char (int ch);
%}

ID		[a-zA-Z0-9_.*?]+
FILENAMECHAR1	[a-zA-Z0-9_/.\\~]
FILENAMECHAR	[^][{}[:space:]():;]+
HEX		0[xX][0-9a-fA-F]+[kKmM]?
OCT		0[0-7]*[kKmM]?
DEC		[0-9]+[kKmM]?
WHITE		[[:space:]]+

%option yylineno
%option never-interactive
%option noyywrap

%x IGNORE

%%
				if (unlikely (ld_scan_version_script))
				  {
				    ld_scan_version_script = -1;
				    return kVERSION_SCRIPT;
				  }

^"#"ifdef/[[:space:]]		{ BEGIN (handle_ifdef ()); }
^"#"else/[[:space:]\n]		{ eat_to_eol (true);
				  push_state (skip_to_endif);
				  BEGIN (IGNORE); }
^"#"elifdef/[[:space:]]		{ eat_to_eol (false);
				  push_state (skip_to_endif);
				  BEGIN (IGNORE); }
^"#"endif/[[:space:]\n]		{ eat_to_eol (true) ; }

<IGNORE>^"#"ifdef/[[:space:]\n] { eat_to_eol (false);
				  push_state (skip_to_endif); }
<IGNORE>^"#"else/[[:space:]\n]	{ eat_to_eol (true);
				  assert (prepdepth > 0);
				  if (prepstate[prepdepth - 1] == skip_if)
				    {
				      /* Back to normal processing.  */
				      assert (prepdepth == 1);
				      BEGIN (pop_state ());
				    }
				}
<IGNORE>^"#"elifdef/[[:space:]]	{ assert (prepdepth > 0);
				  if (prepstate[prepdepth - 1] == skip_if)
				    {
				      /* Maybe this symbol is defined.  */
				      pop_state ();
				      BEGIN (handle_ifdef ());
				    }
				}
<IGNORE>^"#"endif/[[:space:]\n] { eat_to_eol (true);
				  BEGIN (pop_state ()); }
<IGNORE>.|\n			{ /* nothing */ }


"/*"				{ eat_comment (); }

ALIGN				{ return kALIGN; }
ENTRY				{ return kENTRY; }
EXCLUDE_FILE			{ return kEXCLUDE_FILE; }
"global:"			{ return kGLOBAL; }
GROUP				{ return kGROUP; }
INPUT				{ return kINPUT; }
INTERP				{ return kINTERP; }
KEEP				{ return kKEEP; }
"local:"			{ return kLOCAL; }
OUTPUT_FORMAT			{ return kOUTPUT_FORMAT; }
PAGESIZE			{ return kPAGESIZE; }
PROVIDE				{ return kPROVIDE; }
SEARCH_DIR			{ return kSEARCH_DIR; }
SEGMENT				{ return kSEGMENT; }
SIZEOF_HEADERS			{ return kSIZEOF_HEADERS; }
SORT				{ return kSORT; }
VERSION				{ return kVERSION; }

"["([RWX]){0,3}"]"		{ int cnt = 1 ;
				  ldlval.num = 0;
				  while (cnt < yyleng - 1)
				    ldlval.num |= attrib_convert (yytext[cnt++]);
				  return kMODE; }

"{"				{ return '{'; }
"}"				{ return '}'; }
"("				{ return '('; }
")"				{ return ')'; }
":"				{ return ':'; }
";"				{ return ';'; }
"="				{ return '='; }
"+"				{ ldlval.op = exp_plus; return kADD_OP; }
"-"				{ ldlval.op = exp_minus; return kADD_OP; }
"*"				{ return '*'; }
"/"				{ ldlval.op = exp_div; return kMUL_OP; }
"%"				{ ldlval.op = exp_mod; return kMUL_OP; }
"&"				{ return '&'; }
"|"				{ return '|'; }

","				{ return ','; }

{HEX}|{OCT}|{DEC}		{ char *endp;
				  ldlval.num = strtoumax (yytext, &endp, 0);
				  if (*endp != '\0')
				    {
				      if (tolower (*endp) == 'k')
					ldlval.num *= 1024;
				      else
					{
					  assert (tolower (*endp) == 'm');
					  ldlval.num *= 1024 * 1024;
					}
				    }
				  return kNUM; }

{ID}				{ ldlval.str = obstack_strndup (&ld_state.smem,
								yytext, yyleng);
				  return kID; }

{FILENAMECHAR1}{FILENAMECHAR}	{ ldlval.str = obstack_strndup (&ld_state.smem,
								yytext, yyleng);
				  return kFILENAME; }

{WHITE}				{ /* IGNORE */ }

.				{ invalid_char (*yytext); }

%%

static void
eat_comment (void)
{
  while (1)
    {
      int c = input ();

      while (c != '*' && c != EOF)
	c = input ();

      if (c == '*')
	{
	  c = input ();
	  while (c == '*')
	    c = input ();
	  if (c == '/')
	    break;
	}

      if (c == EOF)
	{
	  /* XXX Use the setjmp buffer and signal EOF in comment */
	  error (0, 0, gettext ("EOF in comment"));
	  break;
	}
    }
}


static void
eat_to_eol (bool empty)
{
  bool warned = false;

  while (1)
    {
      int c = input ();

      if (c == EOF)
	break;
      if (c == '\n')
	{
	  ++yylineno;
	  break;
	}

      if (empty && ! isspace (c) && ! warned)
	{
	  error (0, 0, gettext ("%d: garbage at end of line"), yylineno);
	  warned = true;
	}
    }
}


static int
attrib_convert (int c)
{
  if (c == 'X')
    return PF_X;
  if (c == 'W')
    return PF_W;
  assert (c == 'R');
  return PF_R;
}


static void
push_state (enum prepstate state)
{
  if (prepdepth >= MAX_PREPDEPTH)
    error (EXIT_FAILURE, 0, gettext ("%d: conditionals nested too deep"),
	   yylineno);

  prepstate[prepdepth++] = state;
}


static int
pop_state (void)
{
  if (prepdepth == 0)
    error (0, 0, gettext ("%d: unexpected #endif"), yylineno);
  else
    --prepdepth;

  return prepdepth == 0 ? INITIAL : IGNORE;
}


static int
handle_ifdef (void)
{
  char idbuf[50];
  char *id = idbuf;
  size_t idlen = 0;
  size_t idmax = sizeof (idbuf);
  bool ignore_ws = true;
  bool defined = false;
  int result;

  while (1)
    {
      int c = input ();

      if (isspace (c) && ignore_ws)
	continue;

      if (c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z')
	  && (idlen == 0 || c < '0' || c > '9'))
	{
	  unput (c);
	  break;
	}

      if (idlen == idmax)
	{
	  char *newp = (char *) alloca (idmax *= 2);
	  id = memcpy (newp, id, idlen);
	}

      id[idlen++] = c;
      ignore_ws = false;
    }

  /* XXX Compare in a better way.  */
  if (idlen == 6 && strncmp (id, "SHARED", 6) == 0)
    defined = ld_state.file_type == dso_file_type;

  if (defined)
    result = INITIAL;
  else
    {
      push_state (skip_if);
      result = IGNORE;
    }

  return result;
}


static void
invalid_char (int ch)
{
  error (0, 0, (isascii (ch)
		? gettext ("invalid character '%c' at line %d; ignored")
		: gettext ("invalid character '\\%o' at line %d; ignored")),
	 ch, yylineno);
}


// Local Variables:
// mode: C
// End:
