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