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 int ParseChar (StrBuf* B)
56 /* Parse a character. Converts \n into EOL, etc. */
61 /* Check for escape chars */
62 if ((C = SB_Get (B)) == '\\') {
99 /* Hex character constant */
100 C = HexVal (SB_Get (B)) << 4;
101 C |= HexVal (SB_Get (B));
111 while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && I++ < 4) {
112 C = (C << 3) | (SB_Get (B) - '0');
116 Error ("Illegal character constant");
122 /* Return the character */
128 /*****************************************************************************/
130 /*****************************************************************************/
134 void SB_SkipWhite (StrBuf* B)
135 /* Skip whitespace in the string buffer */
137 while (IsBlank (SB_Peek (B))) {
144 int SB_GetSym (StrBuf* B, char* S)
145 /* Get a symbol from the string buffer. S must be able to hold MAX_IDENTLEN
146 * characters. Returns 1 if a symbol was found and 0 otherwise.
149 if (IsIdent (SB_Peek (B))) {
151 char C = SB_Peek (B);
153 if (I < MAX_IDENTLEN) {
159 } while (IsIdent (C) || IsDigit (C));
169 int SB_GetString (StrBuf* B, StrBuf* S)
170 /* Get a string from the string buffer. S will be initialized by the function
171 * and will return the correctly terminated string on return. The function
172 * returns 1 if a string was found and 0 otherwise.
178 *S = AUTO_STRBUF_INITIALIZER;
179 if (SB_Peek (B) == '\"') {
181 /* String follows, be sure to concatenate strings */
182 while (SB_Peek (B) == '\"') {
184 /* Skip the quote char */
187 /* Read the actual string contents */
188 while ((C = SB_Peek (B)) != '\"') {
190 Error ("Unexpected end of string");
193 SB_AppendChar (S, ParseChar (B));
196 /* Skip the closing quote char if there was one */
199 /* Skip white space, read new input */
203 /* Terminate the string */
219 int SB_GetNumber (StrBuf* B, long* Val)
220 /* Get a number from the string buffer. Accepted formats are decimal, octal,
221 * hex and character constants. Numeric constants may be preceeded by a
222 * minus or plus sign. The function returns 1 if a number was found and
234 /* Check for a sign */
236 switch (SB_Peek (B)) {
246 /* Check for the different formats */
253 if (tolower (SB_Peek (B)) == 'x') {
256 if (!IsXDigit (SB_Peek (B))) {
257 Error ("Invalid hexadecimal number");
267 /* Read the number */
268 while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
269 *Val = (*Val * Base) + DigitVal;
273 /* Allow optional 'U' and 'L' modifiers */
275 if (C == 'u' || C == 'U') {
278 if (C == 'l' || C == 'L') {
281 } else if (C == 'l' || C == 'L') {
284 if (C == 'u' || C == 'U') {
289 } else if (C == '\'') {
291 /* Character constant */
293 *Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
294 if (SB_Peek (B) != '\'') {
295 Error ("`\'' expected");
305 Error ("Numeric constant expected");
310 /* Success, value read is in Val */