xref: /netbsd-src/external/bsd/elftosb/dist/elftosb2/ElftosbLexer.cpp (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
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