/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
 */

%option noyywrap nounput noinput never-interactive

%x BYTESTRING
%x PROPNODENAME
%s V1

PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
PATHCHAR	({PROPNODECHAR}|[/])
LABEL		[a-zA-Z_][a-zA-Z0-9_]*
STRING		\"([^\\"]|\\.)*\"
CHAR_LITERAL	'([^']|\\')*'
WS		[[:space:]]
COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
LINECOMMENT	"//".*\n

%{
#include "dtc.h"
#include "srcpos.h"
#include "dtc-parser.tab.h"

extern bool treesource_error;

/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
#define	YY_USER_ACTION \
	{ \
		srcpos_update(&yylloc, yytext, yyleng); \
	}

/*#define LEXDEBUG	1*/

#ifdef LEXDEBUG
#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
#else
#define DPRINT(fmt, ...)	do { } while (0)
#endif

#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
				BEGIN(V1); \

static void push_input_file(const char *filename);
static bool pop_input_file(void);
static void PRINTF(1, 2) lexical_error(const char *fmt, ...);

%}

%%
<*>"/include/"{WS}*{STRING} {
			char *name = strchr(yytext, '\"') + 1;
			yytext[yyleng-1] = '\0';
			push_input_file(name);
		}

<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)* {
			char *line, *fnstart, *fnend;
			struct data fn;
			/* skip text before line # */
			line = yytext;
			while (!isdigit((unsigned char)*line))
				line++;

			/* regexp ensures that first and list "
			 * in the whole yytext are those at
			 * beginning and end of the filename string */
			fnstart = memchr(yytext, '"', yyleng);
			for (fnend = yytext + yyleng - 1;
			     *fnend != '"'; fnend--)
				;
			assert(fnstart && fnend && (fnend > fnstart));

			fn = data_copy_escape_string(fnstart + 1,
						     fnend - fnstart - 1);

			/* Don't allow nuls in filenames */
			if (memchr(fn.val, '\0', fn.len - 1))
				lexical_error("nul in line number directive");

			/* -1 since #line is the number of the next line */
			srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
			data_free(fn);
		}

<*><<EOF>>		{
			if (!pop_input_file()) {
				yyterminate();
			}
		}

<*>{STRING}	{
			DPRINT("String: %s\n", yytext);
			yylval.data = data_copy_escape_string(yytext+1,
					yyleng-2);
			return DT_STRING;
		}

<*>"/dts-v1/"	{
			DPRINT("Keyword: /dts-v1/\n");
			BEGIN_DEFAULT();
			return DT_V1;
		}

<*>"/plugin/"	{
			DPRINT("Keyword: /plugin/\n");
			return DT_PLUGIN;
		}

<*>"/memreserve/"	{
			DPRINT("Keyword: /memreserve/\n");
			BEGIN_DEFAULT();
			return DT_MEMRESERVE;
		}

<*>"/bits/"	{
			DPRINT("Keyword: /bits/\n");
			BEGIN_DEFAULT();
			return DT_BITS;
		}

<*>"/delete-property/"	{
			DPRINT("Keyword: /delete-property/\n");
			DPRINT("<PROPNODENAME>\n");
			BEGIN(PROPNODENAME);
			return DT_DEL_PROP;
		}

<*>"/delete-node/"	{
			DPRINT("Keyword: /delete-node/\n");
			DPRINT("<PROPNODENAME>\n");
			BEGIN(PROPNODENAME);
			return DT_DEL_NODE;
		}

<*>"/omit-if-no-ref/"	{
			DPRINT("Keyword: /omit-if-no-ref/\n");
			DPRINT("<PROPNODENAME>\n");
			BEGIN(PROPNODENAME);
			return DT_OMIT_NO_REF;
		}

<*>{LABEL}:	{
			DPRINT("Label: %s\n", yytext);
			yylval.labelref = xstrdup(yytext);
			yylval.labelref[yyleng-1] = '\0';
			return DT_LABEL;
		}

<V1>{LABEL} 	{
			/* Missed includes or macro definitions while
			 * preprocessing can lead to unexpected identifiers in
			 * the input. Report a slightly more informative error
			 * in this case */

			lexical_error("Unexpected '%s'", yytext);

			/* Treat it as a literal which often generates further
			 * useful error messages */

			yylval.integer = 0;
			return DT_LITERAL;
		}

<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
			char *e;
			DPRINT("Integer Literal: '%s'\n", yytext);

			errno = 0;
			yylval.integer = strtoull(yytext, &e, 0);

			if (*e && e[strspn(e, "UL")]) {
				lexical_error("Bad integer literal '%s'",
					      yytext);
			}

			if (errno == ERANGE)
				lexical_error("Integer literal '%s' out of range",
					      yytext);
			else
				/* ERANGE is the only strtoull error triggerable
				 *  by strings matching the pattern */
				assert(errno == 0);
			return DT_LITERAL;
		}

<*>{CHAR_LITERAL}	{
			struct data d;
			DPRINT("Character literal: %s\n", yytext);

			d = data_copy_escape_string(yytext+1, yyleng-2);
			if (d.len == 1) {
				lexical_error("Empty character literal");
				yylval.integer = 0;
			} else {
				yylval.integer = (unsigned char)d.val[0];

				if (d.len > 2)
					lexical_error("Character literal has %d"
						      " characters instead of 1",
						      d.len - 1);
			}

			data_free(d);
			return DT_CHAR_LITERAL;
		}

<*>\&{LABEL}	{	/* label reference */
			DPRINT("Ref: %s\n", yytext+1);
			yylval.labelref = xstrdup(yytext+1);
			return DT_LABEL_REF;
		}

<*>"&{"{PATHCHAR}*\}	{	/* new-style path reference */
			yytext[yyleng-1] = '\0';
			DPRINT("Ref: %s\n", yytext+2);
			yylval.labelref = xstrdup(yytext+2);
			return DT_PATH_REF;
		}

<BYTESTRING>[0-9a-fA-F]{2} {
			yylval.byte = strtol(yytext, NULL, 16);
			DPRINT("Byte: %02x\n", (int)yylval.byte);
			return DT_BYTE;
		}

<BYTESTRING>"]"	{
			DPRINT("/BYTESTRING\n");
			BEGIN_DEFAULT();
			return ']';
		}

<PROPNODENAME>\\?{PROPNODECHAR}+ {
			DPRINT("PropNodeName: %s\n", yytext);
			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
							yytext + 1 : yytext);
			BEGIN_DEFAULT();
			return DT_PROPNODENAME;
		}

"/incbin/"	{
			DPRINT("Binary Include\n");
			return DT_INCBIN;
		}

<*>{WS}+	/* eat whitespace */
<*>{COMMENT}+	/* eat C-style comments */
<*>{LINECOMMENT}+ /* eat C++-style comments */

<*>"<<"		{ return DT_LSHIFT; };
<*>">>"		{ return DT_RSHIFT; };
<*>"<="		{ return DT_LE; };
<*>">="		{ return DT_GE; };
<*>"=="		{ return DT_EQ; };
<*>"!="		{ return DT_NE; };
<*>"&&"		{ return DT_AND; };
<*>"||"		{ return DT_OR; };

<*>.		{
			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
				(unsigned)yytext[0]);
			if (yytext[0] == '[') {
				DPRINT("<BYTESTRING>\n");
				BEGIN(BYTESTRING);
			}
			if ((yytext[0] == '{')
			    || (yytext[0] == ';')) {
				DPRINT("<PROPNODENAME>\n");
				BEGIN(PROPNODENAME);
			}
			return yytext[0];
		}

%%

static void push_input_file(const char *filename)
{
	assert(filename);

	srcfile_push(filename);

	yyin = current_srcfile->f;

	yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
}


static bool pop_input_file(void)
{
	if (srcfile_pop() == 0)
		return false;

	yypop_buffer_state();
	yyin = current_srcfile->f;

	return true;
}

static void lexical_error(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	srcpos_verror(&yylloc, "Lexical error", fmt, ap);
	va_end(ap);

	treesource_error = true;
}
