1 /*
2 * File: ElftosbLexer.cpp
3 *
4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
6 */
7 #include "ElftosbLexer.h"
8 #include <algorithm>
9 #include "HexValues.h"
10
11 using namespace elftosb;
12
ElftosbLexer(istream & inputStream)13 ElftosbLexer::ElftosbLexer(istream & inputStream)
14 : yyFlexLexer(&inputStream), m_line(1), m_blob(0), m_blobFirstLine(0)
15 {
16 }
17
getSymbolValue(YYSTYPE * value)18 void ElftosbLexer::getSymbolValue(YYSTYPE * value)
19 {
20 if (!value)
21 {
22 return;
23 }
24 *value = m_symbolValue;
25 }
26
addSourceName(std::string * ident)27 void ElftosbLexer::addSourceName(std::string * ident)
28 {
29 m_sources.push_back(*ident);
30 }
31
isSourceName(std::string * ident)32 bool ElftosbLexer::isSourceName(std::string * ident)
33 {
34 string_vector_t::iterator it = find(m_sources.begin(), m_sources.end(), *ident);
35 return it != m_sources.end();
36 }
37
LexerError(const char * msg)38 void ElftosbLexer::LexerError(const char * msg)
39 {
40 throw elftosb::lexical_error(msg);
41 }
42
43 //! Reads the \a in string and writes to the \a out string. These strings can be the same
44 //! string since the read head is always in front of the write head.
45 //!
46 //! \param[in] in Input string containing C-style escape sequences.
47 //! \param[out] out Output string. All escape sequences in the input string have been converted
48 //! to the actual characters. May point to the same string as \a in.
49 //! \return The length of the resulting \a out string. This length is necessary because
50 //! the string may have contained escape sequences that inserted null characters.
processStringEscapes(const char * in,char * out)51 int ElftosbLexer::processStringEscapes(const char * in, char * out)
52 {
53 int count = 0;
54 while (*in)
55 {
56 switch (*in)
57 {
58 case '\\':
59 {
60 // start of an escape sequence
61 char c = *++in;
62 switch (c)
63 {
64 case 0: // end of the string, bail
65 break;
66 case 'x':
67 {
68 // start of a hex char escape sequence
69
70 // read high and low nibbles, checking for end of string
71 char hi = *++in;
72 if (hi == 0) break;
73 char lo = *++in;
74 if (lo == 0) break;
75
76 if (isHexDigit(hi) && isHexDigit(lo))
77 {
78 if (hi >= '0' && hi <= '9')
79 c = (hi - '0') << 4;
80 else if (hi >= 'A' && hi <= 'F')
81 c = (hi - 'A' + 10) << 4;
82 else if (hi >= 'a' && hi <= 'f')
83 c = (hi - 'a' + 10) << 4;
84
85 if (lo >= '0' && lo <= '9')
86 c |= lo - '0';
87 else if (lo >= 'A' && lo <= 'F')
88 c |= lo - 'A' + 10;
89 else if (lo >= 'a' && lo <= 'f')
90 c |= lo - 'a' + 10;
91
92 *out++ = c;
93 count++;
94 }
95 else
96 {
97 // not hex digits, the \x must have wanted an 'x' char
98 *out++ = 'x';
99 *out++ = hi;
100 *out++ = lo;
101 count += 3;
102 }
103 break;
104 }
105 case 'n':
106 *out++ = '\n';
107 count++;
108 break;
109 case 't':
110 *out++ = '\t';
111 count++;
112 break;
113 case 'r':
114 *out++ = '\r';
115 count++;
116 break;
117 case 'b':
118 *out++ = '\b';
119 count++;
120 break;
121 case 'f':
122 *out++ = '\f';
123 count++;
124 break;
125 case '0':
126 *out++ = '\0';
127 count++;
128 break;
129 default:
130 *out++ = c;
131 count++;
132 break;
133 }
134 break;
135 }
136
137 default:
138 // copy all other chars directly
139 *out++ = *in++;
140 count++;
141 }
142 }
143
144 // place terminating null char on output
145 *out = 0;
146 return count;
147 }
148
149
150