1 /******************************************************************************
2 * Copyright (c) 2000-2014 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 ******************************************************************************/
9 %option never-interactive
11 %option prefix="charstring_"
14 // Scanner to transform string literals from external representation
15 // to internal representation.
17 #include "../../common/dbgnew.hh"
19 #include "../string.hh"
20 #include "../Setting.hh"
21 #include "../CompilerError.hh"
23 using namespace Common;
25 #define INITIAL_BUFFER_SIZE 32
27 static void add_char(char*& string_ptr, size_t& string_len,
28 size_t& string_size, char c)
30 if (string_size <= string_len) {
32 string_ptr = (char*)Realloc(string_ptr, string_size);
34 string_ptr[string_len++] = c;
37 #define ADD_CHAR(c) add_char(string_ptr, string_len, string_size, c)
39 #define YY_DECL static string *yylex(const char *current_file, \
40 int current_line, int current_column)
48 char *string_ptr = (char*)Malloc(INITIAL_BUFFER_SIZE);
49 size_t string_len = 0, string_size = INITIAL_BUFFER_SIZE;
51 /* Two consecutive doublequotes -> one doublequotequote */
52 ["]["] ADD_CHAR('"'); current_column += 2;
54 /* Backslash-escaped singlequote, doublequote, question mark or backslash */
55 \\[''""?\\] ADD_CHAR(yytext[1]); current_column += 2;
57 /* C-style backslash-escapes */
58 \\a ADD_CHAR('\a'); current_column += 2;
59 \\b ADD_CHAR('\b'); current_column += 2;
60 \\f ADD_CHAR('\f'); current_column += 2;
61 \\n ADD_CHAR('\n'); current_column += 2;
62 \\r ADD_CHAR('\r'); current_column += 2;
63 \\t ADD_CHAR('\t'); current_column += 2;
64 \\v ADD_CHAR('\v'); current_column += 2;
68 if (yyleng == 4 && yytext[1] > '3') {
69 Location loc(current_file, current_line, current_column, current_line,
71 loc.error("Invalid octal character code: `%s'", yytext);
74 char c = yytext[1] - '0';
75 if (yyleng >= 3) c = c * 8 + yytext[2] - '0';
76 if (yyleng == 4) c = c * 8 + yytext[3] - '0';
79 current_column += yyleng;
83 /* hexadecimal notation */
85 if (yytext[2] >= 'A' && yytext[2] <= 'F') c = yytext[2] - 'A' + 10;
86 else if (yytext[2] >= 'a' && yytext[2] <= 'f') c = yytext[2] - 'a' + 10;
87 else c = yytext[2] - '0';
89 if (yytext[3] >= 'A' && yytext[3] <= 'F')
90 c = c * 16 + yytext[3] - 'A' + 10;
91 else if (yytext[3] >= 'a' && yytext[3] <= 'f')
92 c = c * 16 + yytext[3] - 'a' + 10;
93 else c = c * 16 + yytext[3] - '0';
96 current_column += yyleng;
100 /* escaped newline character */
105 \\[][dsw()|^*#+-] { /* '-' is non-special as last character, ']' as first */
106 /* temporary hack: these escape sequences are handled transparently
107 as they can appear in the second argument of regexp().
108 In effect, they are re-escaped (both backslash and the next char survive),
109 saving the user from having to double-escape them.
110 Unfortunately, we don't know yet whether this string is being used
111 as an argument to regexp(), so we can't suppress the warning. */
112 Location loc(current_file, current_line, current_column, current_line,
113 current_column + yyleng);
114 loc.warning("Unknown escape sequence `%s' was treated literally", yytext);
115 for (int i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]);
120 Location loc(current_file, current_line, current_column, current_line,
121 current_column + yyleng);
122 loc.error("Invalid escape sequence: `%s'", yytext);
123 current_column += yyleng;
127 Location loc(current_file, current_line, current_column, current_line + 1, 0);
128 loc.warning("Unescaped newline character");
129 for (int i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]);
134 [""\\] FATAL_ERROR("charstring_lex(): invalid single `%s'", yytext);
136 . ADD_CHAR(yytext[0]); current_column++;
139 string *ret_val = new string(string_len, string_ptr);
146 string *parse_charstring_value(const char *str, const Location& loc)
148 Error_Context cntxt(&loc, "In charstring value");
149 struct yy_buffer_state *flex_buffer = charstring__scan_string(str);
151 FATAL_ERROR("parse_charstring_value(): flex buffer creation failed");
154 string *ret_val = yylex(loc.get_filename(), loc.get_first_line(),
155 loc.get_first_column() + 1);
156 charstring_lex_destroy();