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. */
62 /* Check for escape chars */
63 if ((C = SB_Get (B)) == '\\') {
64 switch (SB_Peek (B)) {
111 /* Hex character constant */
113 C = HexVal (SB_Get (B)) << 4;
114 C |= HexVal (SB_Get (B));
126 Val = SB_Get (B) - '0';
127 while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && ++I <= 3) {
128 Val = (Val << 3) | (SB_Get (B) - '0');
132 Error ("Character constant out of range");
137 Error ("Illegal character constant 0x%02X", SB_Get (B));
143 /* Return the character */
149 /*****************************************************************************/
151 /*****************************************************************************/
155 void SB_SkipWhite (StrBuf* B)
156 /* Skip whitespace in the string buffer */
158 while (IsBlank (SB_Peek (B))) {
165 int SB_GetSym (StrBuf* B, char* S)
166 /* Get a symbol from the string buffer. S must be able to hold MAX_IDENTLEN
167 * characters. Returns 1 if a symbol was found and 0 otherwise.
170 if (IsIdent (SB_Peek (B))) {
172 char C = SB_Peek (B);
174 if (I < MAX_IDENTLEN) {
180 } while (IsIdent (C) || IsDigit (C));
190 int SB_GetString (StrBuf* B, StrBuf* S)
191 /* Get a string from the string buffer. S will be initialized by the function
192 * and will return the correctly terminated string on return. The function
193 * returns 1 if a string was found and 0 otherwise.
199 *S = AUTO_STRBUF_INITIALIZER;
200 if (SB_Peek (B) == '\"') {
202 /* String follows, be sure to concatenate strings */
203 while (SB_Peek (B) == '\"') {
205 /* Skip the quote char */
208 /* Read the actual string contents */
209 while ((C = SB_Peek (B)) != '\"') {
211 Error ("Unexpected end of string");
214 SB_AppendChar (S, ParseChar (B));
217 /* Skip the closing quote char if there was one */
220 /* Skip white space, read new input */
224 /* Terminate the string */
240 int SB_GetNumber (StrBuf* B, long* Val)
241 /* Get a number from the string buffer. Accepted formats are decimal, octal,
242 * hex and character constants. Numeric constants may be preceeded by a
243 * minus or plus sign. The function returns 1 if a number was found and
255 /* Check for a sign */
257 switch (SB_Peek (B)) {
267 /* Check for the different formats */
274 if (tolower (SB_Peek (B)) == 'x') {
277 if (!IsXDigit (SB_Peek (B))) {
278 Error ("Invalid hexadecimal number");
288 /* Read the number */
289 while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
290 *Val = (*Val * Base) + DigitVal;
294 /* Allow optional 'U' and 'L' modifiers */
296 if (C == 'u' || C == 'U') {
299 if (C == 'l' || C == 'L') {
302 } else if (C == 'l' || C == 'L') {
305 if (C == 'u' || C == 'U') {
310 } else if (C == '\'') {
312 /* Character constant */
314 *Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
315 if (SB_Peek (B) != '\'') {
316 Error ("`\'' expected");
326 Error ("Numeric constant expected");
331 /* Success, value read is in Val */