]> git.sur5r.net Git - cc65/blob - src/da65/asminc.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / da65 / asminc.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 asminc.c                                  */
4 /*                                                                           */
5 /*             Read an assembler include file containing symbols             */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2005-2008 Ullrich von Bassewitz                                       */
10 /*               Roemerstrasse 52                                            */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
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.                                    */
18 /*                                                                           */
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:                            */
22 /*                                                                           */
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              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdio.h>
37 #include <errno.h>
38
39 /* common */
40 #include "chartype.h"
41 #include "strbuf.h"
42
43 /* da65 */
44 #include "asminc.h"
45 #include "comments.h"
46 #include "error.h"
47 #include "labels.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Code                                    */
53 /*****************************************************************************/
54
55
56
57 static char* SkipWhitespace (char* L)
58 /* Ignore white space in L */
59 {
60     while (IsBlank (*L)) {
61         ++L;
62     }
63     return L;
64 }
65
66
67
68 unsigned DigitVal (unsigned char C)
69 /* Return the value of the given digit */
70 {
71     if (IsDigit (C)) {
72         return C - '0';
73     } else {
74         return tolower (C) - 'a' + 10;
75     }
76 }
77
78
79
80 void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
81 /* Read an assembler include file */
82 {
83     char        Buf[1024];
84     char*       L;
85     const char* Comment;
86     unsigned    Line;
87     unsigned    Len;
88     long        Val;
89     unsigned    DVal;
90     int         Sign;
91     unsigned    Base;
92     unsigned    Digits;
93     StrBuf      Ident = STATIC_STRBUF_INITIALIZER;
94
95     /* Try to open the file for reading */
96     FILE* F = fopen (Filename, "r");
97     if (F == 0) {
98         Error ("Cannot open asm include file \"%s\": %s",
99                Filename, strerror (errno));
100     }
101
102     /* Read line by line, check for NAME = VALUE lines */
103     Line = 0;
104     while ((L = fgets (Buf, sizeof (Buf), F)) != 0) {
105
106         /* One more line read */
107         ++Line;
108
109         /* Ignore leading white space */
110         while (IsBlank (*L)) {
111             ++L;
112         }
113
114         /* Remove trailing whitespace */
115         Len = strlen (L);
116         while (Len > 0 && IsSpace (L[Len-1])) {
117             --Len;
118         }
119         L[Len] = '\0';
120
121         /* If the line is empty or starts with a comment char, ignore it */
122         if (*L == '\0' || *L == CommentStart) {
123             continue;
124         }
125
126         /* Read an identifier */
127         SB_Clear (&Ident);
128         if (IsAlpha (*L) || *L == '_') {
129             SB_AppendChar (&Ident, *L++);
130             while (IsAlNum (*L) || *L == '_') {
131                 SB_AppendChar (&Ident, *L++);
132             }
133             SB_Terminate (&Ident);
134         } else {
135             if (!IgnoreUnknown) {
136                 Error ("%s(%u): Syntax error", Filename, Line);
137             }
138             continue;
139         }
140
141         /* Ignore white space */
142         L = SkipWhitespace (L);
143
144         /* Check for := or = */
145         if (*L == '=') {
146             ++L;
147         } else if (*L == ':' && *++L == '=') {
148             ++L;
149         } else {
150             if (!IgnoreUnknown) {
151                 Error ("%s(%u): Missing `='", Filename, Line);
152             }
153             continue;
154         }
155
156         /* Allow white space once again */
157         L = SkipWhitespace (L);
158
159         /* A number follows. Read the sign. */
160         if (*L == '-') {
161             Sign = -1;
162             ++L;
163         } else {
164             Sign = 1;
165             if (*L == '+') {
166                 ++L;
167             }
168         }
169
170         /* Determine the base of the number. Allow $ and % as prefixes for
171          * hex and binary numbers respectively.
172          */
173         if (*L == '$') {
174             Base = 16;
175             ++L;
176         } else if (*L == '%') {
177             Base = 2;
178             ++L;
179         } else {
180             Base = 10;
181         }
182
183         /* Decode the number */
184         Digits = 0;
185         Val = 0;
186         while (IsXDigit (*L) && (DVal = DigitVal (*L)) < Base) {
187             Val = (Val * Base) + DVal;
188             ++Digits;
189             ++L;
190         }
191
192         /* Must have at least one digit */
193         if (Digits == 0) {
194             if (!IgnoreUnknown) {
195                 Error ("%s(%u): Error in number format", Filename, Line);
196             }
197             continue;
198         }
199
200         /* Skip whitespace again */
201         L = SkipWhitespace (L);
202
203         /* Check for a comment */
204         if (*L == CommentStart) {
205             Comment = SkipWhitespace (L+1);
206             if (*Comment == '\0') {
207                 Comment = 0;
208             }
209         } else {
210             Comment = 0;
211         }
212
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);
217             }
218             continue;
219         }
220
221         /* Apply the sign */
222         Val *= Sign;
223
224         /* Define the symbol and the comment */
225         AddExtLabel (Val, SB_GetConstBuf (&Ident));
226         SetComment (Val, Comment);
227
228     }
229
230     /* Delete the string buffer contents */
231     SB_Done (&Ident);
232
233     /* Close the include file ignoring errors (we were just reading). */
234     (void) fclose (F);
235 }
236
237
238