1 /*****************************************************************************/
5 /* Read an assembler include file containing symbols */
9 /* (C) 2005-2008 Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
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 /*****************************************************************************/
51 /*****************************************************************************/
53 /*****************************************************************************/
57 static char* SkipWhitespace (char* L)
58 /* Ignore white space in L */
60 while (IsBlank (*L)) {
68 unsigned DigitVal (unsigned char C)
69 /* Return the value of the given digit */
74 return tolower (C) - 'a' + 10;
80 void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
81 /* Read an assembler include file */
93 StrBuf Ident = STATIC_STRBUF_INITIALIZER;
95 /* Try to open the file for reading */
96 FILE* F = fopen (Filename, "r");
98 Error ("Cannot open asm include file \"%s\": %s",
99 Filename, strerror (errno));
102 /* Read line by line, check for NAME = VALUE lines */
104 while ((L = fgets (Buf, sizeof (Buf), F)) != 0) {
106 /* One more line read */
109 /* Ignore leading white space */
110 while (IsBlank (*L)) {
114 /* Remove trailing whitespace */
116 while (Len > 0 && IsSpace (L[Len-1])) {
121 /* If the line is empty or starts with a comment char, ignore it */
122 if (*L == '\0' || *L == CommentStart) {
126 /* Read an identifier */
128 if (IsAlpha (*L) || *L == '_') {
129 SB_AppendChar (&Ident, *L++);
130 while (IsAlNum (*L) || *L == '_') {
131 SB_AppendChar (&Ident, *L++);
133 SB_Terminate (&Ident);
135 if (!IgnoreUnknown) {
136 Error ("%s(%u): Syntax error", Filename, Line);
141 /* Ignore white space */
142 L = SkipWhitespace (L);
144 /* Check for := or = */
147 } else if (*L == ':' && *++L == '=') {
150 if (!IgnoreUnknown) {
151 Error ("%s(%u): Missing `='", Filename, Line);
156 /* Allow white space once again */
157 L = SkipWhitespace (L);
159 /* A number follows. Read the sign. */
170 /* Determine the base of the number. Allow $ and % as prefixes for
171 * hex and binary numbers respectively.
176 } else if (*L == '%') {
183 /* Decode the number */
186 while (IsXDigit (*L) && (DVal = DigitVal (*L)) < Base) {
187 Val = (Val * Base) + DVal;
192 /* Must have at least one digit */
194 if (!IgnoreUnknown) {
195 Error ("%s(%u): Error in number format", Filename, Line);
200 /* Skip whitespace again */
201 L = SkipWhitespace (L);
203 /* Check for a comment */
204 if (*L == CommentStart) {
205 Comment = SkipWhitespace (L+1);
206 if (*Comment == '\0') {
213 /* Check for a comment character or end of line */
214 if (*L != CommentStart && *L != '\0') {
215 if (!IgnoreUnknown) {
216 Error ("%s(%u): Trailing garbage", Filename, Line);
224 /* Define the symbol and the comment */
225 AddExtLabel (Val, SB_GetConstBuf (&Ident));
226 SetComment (Val, Comment);
230 /* Delete the string buffer contents */
233 /* Close the include file ignoring errors (we were just reading). */