1 /*****************************************************************************/
5 /* Small scanner for input from a StrBuf */
9 /* (C) 2002 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
45 #include "scanstrbuf.h"
49 /*****************************************************************************/
50 /* Helper functions */
51 /*****************************************************************************/
55 static char ParseChar (StrBuf* B)
56 /* Parse a character. Converts \n into EOL, etc. */
61 /* Check for escape chars */
62 if ((C = SB_Get (B)) == '\\') {
90 /* Hex character constant */
91 C = HexVal (SB_Get (B)) << 4;
92 C |= HexVal (SB_Get (B));
102 while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && I++ < 4) {
103 C = (C << 3) | (SB_Get (B) - '0');
107 Error ("Illegal character constant");
113 /* Return the character */
123 /*****************************************************************************/
125 /*****************************************************************************/
129 void SB_SkipWhite (StrBuf* B)
130 /* Skip whitespace in the string buffer */
132 while (IsBlank (SB_Peek (B))) {
139 int SB_GetSym (StrBuf* B, char* S)
140 /* Get a symbol from the string buffer. S must be able to hold MAX_IDENTLEN
141 * characters. Returns 1 if a symbol was found and 0 otherwise.
144 if (IsIdent (SB_Peek (B))) {
146 char C = SB_Peek (B);
148 if (I < MAX_IDENTLEN) {
154 } while (IsIdent (C) || IsDigit (C));
164 int SB_GetString (StrBuf* B, StrBuf* S)
165 /* Get a string from the string buffer. S will be initialized by the function
166 * and will return the correctly terminated string on return. The function
167 * returns 1 if a string was found and 0 otherwise.
173 *S = AUTO_STRBUF_INITIALIZER;
174 if (SB_Peek (B) == '\"') {
176 /* String follows, be sure to concatenate strings */
177 while (SB_Peek (B) == '\"') {
179 /* Skip the quote char */
182 /* Read the actual string contents */
183 while ((C = SB_Peek (B)) != '\"') {
185 Error ("Unexpected end of string");
188 SB_AppendChar (S, ParseChar (B));
191 /* Skip the closing quote char if there was one */
194 /* Skip white space, read new input */
198 /* Terminate the string */
214 int SB_GetNumber (StrBuf* B, long* Val)
215 /* Get a number from the string buffer. Accepted formats are decimal, octal,
216 * hex and character constants. Numeric constants may be preceeded by a
217 * minus or plus sign. The function returns 1 if a number was found and
229 /* Check for a sign */
231 switch (SB_Peek (B)) {
241 /* Check for the different formats */
248 if (tolower (SB_Peek (B)) == 'x') {
251 if (!IsXDigit (SB_Peek (B))) {
252 Error ("Invalid hexadecimal number");
262 /* Read the number */
263 while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
264 *Val = (*Val * Base) + DigitVal;
268 /* Allow optional 'U' and 'L' modifiers */
270 if (C == 'u' || C == 'U') {
273 if (C == 'l' || C == 'L') {
276 } else if (C == 'l' || C == 'L') {
279 if (C == 'u' || C == 'U') {
284 } else if (C == '\'') {
286 /* Character constant */
288 *Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
289 if (SB_Peek (B) != '\'') {
290 Error ("`\'' expected");
300 Error ("Numeric constant expected");
305 /* Success, value read is in Val */