Commit | Line | Data |
---|---|---|
970ed795 | 1 | /****************************************************************************** |
3abe9331 | 2 | * Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
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 | ******************************************************************************/ | |
8 | %option noyywrap | |
9 | %option never-interactive | |
10 | %option nounput | |
11 | %option prefix="charstring_" | |
12 | ||
13 | %{ | |
14 | // Scanner to transform string literals from external representation | |
15 | // to internal representation. | |
16 | ||
17 | #include "../../common/dbgnew.hh" | |
18 | #include "../error.h" | |
19 | #include "../string.hh" | |
20 | #include "../Setting.hh" | |
21 | #include "../CompilerError.hh" | |
22 | ||
23 | using namespace Common; | |
24 | ||
25 | #define INITIAL_BUFFER_SIZE 32 | |
26 | ||
27 | static void add_char(char*& string_ptr, size_t& string_len, | |
28 | size_t& string_size, char c) | |
29 | { | |
30 | if (string_size <= string_len) { | |
31 | string_size *= 2; | |
32 | string_ptr = (char*)Realloc(string_ptr, string_size); | |
33 | } | |
34 | string_ptr[string_len++] = c; | |
35 | } | |
36 | ||
37 | #define ADD_CHAR(c) add_char(string_ptr, string_len, string_size, c) | |
38 | ||
39 | #define YY_DECL static string *yylex(const char *current_file, \ | |
40 | int current_line, int current_column) | |
41 | ||
42 | %} | |
43 | ||
44 | NEWLINE \r|\n|\r\n | |
45 | HEXDIGIT [0-9A-Fa-f] | |
46 | ||
47 | %% | |
48 | char *string_ptr = (char*)Malloc(INITIAL_BUFFER_SIZE); | |
49 | size_t string_len = 0, string_size = INITIAL_BUFFER_SIZE; | |
50 | ||
51 | /* Two consecutive doublequotes -> one doublequotequote */ | |
52 | ["]["] ADD_CHAR('"'); current_column += 2; | |
53 | ||
54 | /* Backslash-escaped singlequote, doublequote, question mark or backslash */ | |
55 | \\[''""?\\] ADD_CHAR(yytext[1]); current_column += 2; | |
56 | ||
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; | |
65 | ||
66 | \\[0-7]{1,3} { | |
67 | /* octal notation */ | |
68 | if (yyleng == 4 && yytext[1] > '3') { | |
69 | Location loc(current_file, current_line, current_column, current_line, | |
70 | current_column + 4); | |
71 | loc.error("Invalid octal character code: `%s'", yytext); | |
72 | ADD_CHAR('\377'); | |
73 | } else { | |
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'; | |
77 | ADD_CHAR(c); | |
78 | } | |
79 | current_column += yyleng; | |
80 | } | |
81 | ||
82 | \\x{HEXDIGIT}{1,2} { | |
83 | /* hexadecimal notation */ | |
84 | char c; | |
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'; | |
88 | if (yyleng == 4) { | |
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'; | |
94 | } | |
95 | ADD_CHAR(c); | |
96 | current_column += yyleng; | |
97 | } | |
98 | ||
99 | \\{NEWLINE} { | |
100 | /* escaped newline character */ | |
101 | current_line++; | |
102 | current_column = 0; | |
103 | } | |
104 | ||
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); | |
3abe9331 | 115 | for (size_t i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]); |
970ed795 EL |
116 | current_column += 2; |
117 | } | |
118 | ||
119 | \\(x[^\\""]|.) { | |
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; | |
124 | } | |
125 | ||
126 | {NEWLINE} { | |
127 | Location loc(current_file, current_line, current_column, current_line + 1, 0); | |
128 | loc.warning("Unescaped newline character"); | |
3abe9331 | 129 | for (size_t i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]); |
970ed795 EL |
130 | current_line++; |
131 | current_column = 0; | |
132 | } | |
133 | ||
134 | [""\\] FATAL_ERROR("charstring_lex(): invalid single `%s'", yytext); | |
135 | ||
136 | . ADD_CHAR(yytext[0]); current_column++; | |
137 | ||
138 | <<EOF>> { | |
139 | string *ret_val = new string(string_len, string_ptr); | |
140 | Free(string_ptr); | |
141 | return ret_val; | |
142 | } | |
143 | ||
144 | %% | |
145 | ||
146 | string *parse_charstring_value(const char *str, const Location& loc) | |
147 | { | |
148 | Error_Context cntxt(&loc, "In charstring value"); | |
149 | struct yy_buffer_state *flex_buffer = charstring__scan_string(str); | |
150 | if (!flex_buffer) { | |
151 | FATAL_ERROR("parse_charstring_value(): flex buffer creation failed"); | |
152 | return 0; | |
153 | } | |
154 | string *ret_val = yylex(loc.get_filename(), loc.get_first_line(), | |
155 | loc.get_first_column() + 1); | |
156 | charstring_lex_destroy(); | |
157 | return ret_val; | |
158 | } |