-
Adam Knapp authored
Change-Id: Iacba53d8499439eba82045c30a1e0f2e0edf16fe Signed-off-by:
Adam Knapp <adam.knapp@sigmatechnology.se>
Adam Knapp authoredChange-Id: Iacba53d8499439eba82045c30a1e0f2e0edf16fe Signed-off-by:
Adam Knapp <adam.knapp@sigmatechnology.se>
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
charstring_la.l 5.04 KiB
/******************************************************************************
* Copyright (c) 2000-2021 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Balasko, Jeno
* Raduly, Csaba
* Szabados, Kristof
* Szabo, Janos Zoltan – initial implementation
*
******************************************************************************/
%option noyywrap
%option never-interactive
%option nounput
%option prefix="charstring_"
%{
// Scanner to transform string literals from external representation
// to internal representation.
#include "../../common/dbgnew.hh"
#include "../error.h"
#include "../string.hh"
#include "../Setting.hh"
#include "../CompilerError.hh"
using namespace Common;
#define INITIAL_BUFFER_SIZE 32
static void add_char(char*& string_ptr, size_t& string_len,
size_t& string_size, char c)
{
if (string_size <= string_len) {
string_size *= 2;
string_ptr = (char*)Realloc(string_ptr, string_size);
}
string_ptr[string_len++] = c;
}
#define ADD_CHAR(c) add_char(string_ptr, string_len, string_size, c)
#define YY_DECL static string *yylex(const char *current_file, \
size_t current_line, size_t current_column)
%}
NEWLINE \r|\n|\r\n
HEXDIGIT [0-9A-Fa-f]
%%
char *string_ptr = (char*)Malloc(INITIAL_BUFFER_SIZE);
size_t string_len = 0, string_size = INITIAL_BUFFER_SIZE;
/* Two consecutive doublequotes -> one doublequotequote */
["]["] ADD_CHAR('"'); current_column += 2;
/* Backslash-escaped singlequote, doublequote, question mark or backslash */
\\[''""?\\] ADD_CHAR(yytext[1]); current_column += 2;
/* C-style backslash-escapes */
\\a ADD_CHAR('\a'); current_column += 2;
\\b ADD_CHAR('\b'); current_column += 2;
\\f ADD_CHAR('\f'); current_column += 2;
\\n ADD_CHAR('\n'); current_column += 2;
\\r ADD_CHAR('\r'); current_column += 2;
\\t ADD_CHAR('\t'); current_column += 2;
\\v ADD_CHAR('\v'); current_column += 2;
\\[0-7]{1,3} {
/* octal notation */
if (yyleng == 4 && yytext[1] > '3') {
Location loc(current_file, current_line, current_column, current_line,
current_column + 4);
loc.error("Invalid octal character code: `%s'", yytext);
ADD_CHAR('\377');
} else {
char c = yytext[1] - '0';
if (yyleng >= 3) c = c * 8 + yytext[2] - '0';
if (yyleng == 4) c = c * 8 + yytext[3] - '0';
ADD_CHAR(c);
}
current_column += yyleng;
}
\\x{HEXDIGIT}{1,2} {
/* hexadecimal notation */
char c;
if (yytext[2] >= 'A' && yytext[2] <= 'F') c = yytext[2] - 'A' + 10;
else if (yytext[2] >= 'a' && yytext[2] <= 'f') c = yytext[2] - 'a' + 10;
else c = yytext[2] - '0';
if (yyleng == 4) {
if (yytext[3] >= 'A' && yytext[3] <= 'F')
c = c * 16 + yytext[3] - 'A' + 10;
else if (yytext[3] >= 'a' && yytext[3] <= 'f')
c = c * 16 + yytext[3] - 'a' + 10;
else c = c * 16 + yytext[3] - '0';
}
ADD_CHAR(c);
current_column += yyleng;
}
\\{NEWLINE} {
/* escaped newline character */
current_line++;
current_column = 0;
}
\\[][dsw()|^*#+-] { /* '-' is non-special as last character, ']' as first */
/* temporary hack: these escape sequences are handled transparently
as they can appear in the second argument of regexp().
In effect, they are re-escaped (both backslash and the next char survive),
saving the user from having to double-escape them.
Unfortunately, we don't know yet whether this string is being used
as an argument to regexp(), so we can't suppress the warning. */
Location loc(current_file, current_line, current_column, current_line,
current_column + yyleng);
loc.warning("Unknown escape sequence `%s' was treated literally", yytext);
for (size_t i = 0; i < (size_t)yyleng; i++) ADD_CHAR(yytext[i]);
current_column += 2;
}
\\(x[^\\""]|.) {
Location loc(current_file, current_line, current_column, current_line,
current_column + yyleng);
loc.error("Invalid escape sequence: `%s'", yytext);
current_column += yyleng;
}
{NEWLINE} {
Location loc(current_file, current_line, current_column, current_line + 1, 0);
loc.warning("Unescaped newline character");
for (size_t i = 0; i < (size_t)yyleng; i++) ADD_CHAR(yytext[i]);
current_line++;
current_column = 0;
}
[""\\] FATAL_ERROR("charstring_lex(): invalid single `%s'", yytext);
. ADD_CHAR(yytext[0]); current_column++;
<<EOF>> {
string *ret_val = new string(string_len, string_ptr);
Free(string_ptr);
return ret_val;
}
%%
string *parse_charstring_value(const char *str, const Location& loc)
{
Error_Context cntxt(&loc, "In charstring value");
struct yy_buffer_state *flex_buffer = charstring__scan_string(str);
if (!flex_buffer) {
FATAL_ERROR("parse_charstring_value(): flex buffer creation failed");
return 0;
}
string *ret_val = yylex(loc.get_filename(), loc.get_first_line(),
loc.get_first_column() + 1);
charstring_lex_destroy();
return ret_val;
}