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 13 ElftosbLexer::ElftosbLexer(istream & inputStream) 14 : yyFlexLexer(&inputStream), m_line(1), m_blob(0), m_blobFirstLine(0) 15 { 16 } 17 18 void ElftosbLexer::getSymbolValue(YYSTYPE * value) 19 { 20 if (!value) 21 { 22 return; 23 } 24 *value = m_symbolValue; 25 } 26 27 void ElftosbLexer::addSourceName(std::string * ident) 28 { 29 m_sources.push_back(*ident); 30 } 31 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 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. 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