]> git.sur5r.net Git - cc65/blob - src/da65/config.c
Added dword tables, char comments etc.
[cc65] / src / da65 / config.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 config.c                                  */
4 /*                                                                           */
5 /*                 Disassembler configuration file handling                  */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000     Ullrich von Bassewitz                                        */
10 /*              Wacholderweg 14                                              */
11 /*              D-70597 Stuttgart                                            */
12 /* EMail:       uz@musoftware.de                                             */
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 #if defined(_MSC_VER)
37 /* Microsoft compiler */
38 #  include <io.h>
39 #else
40 /* Anyone else */
41 #  include <unistd.h>
42 #endif
43
44 /* common */
45 #include "xmalloc.h"
46
47 /* da65 */
48 #include "attrtab.h"
49 #include "error.h"
50 #include "global.h"
51 #include "scanner.h"
52 #include "config.h"
53
54
55
56 /*****************************************************************************/
57 /*                                   Code                                    */
58 /*****************************************************************************/
59
60
61
62 static void GlobalSection (void)
63 /* Parse a global section */
64 {
65     static const IdentTok GlobalDefs[] = {
66         {   "INPUTNAME",        CFGTOK_INPUTNAME        },
67         {   "OUTPUTNAME",       CFGTOK_OUTPUTNAME       },
68         {   "PAGELENGTH",       CFGTOK_PAGELENGTH       },
69     };
70
71     /* Skip the token */
72     CfgNextTok ();
73
74     /* Expect the opening curly brace */
75     CfgConsumeLCurly ();
76
77     /* Look for section tokens */
78     while (CfgTok != CFGTOK_RCURLY) {
79
80         /* Convert to special token */
81         CfgSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive");
82
83         /* Look at the token */
84         switch (CfgTok) {
85
86             case CFGTOK_INPUTNAME:
87                 CfgNextTok ();
88                 CfgAssureStr ();
89                 if (InFile) {
90                     CfgError ("Input file name already given");
91                 }
92                 InFile = xstrdup (CfgSVal);
93                 CfgNextTok ();
94                 break;
95
96             case CFGTOK_OUTPUTNAME:
97                 CfgNextTok ();
98                 CfgAssureStr ();
99                 if (OutFile) {
100                     CfgError ("Output file name already given");
101                 }
102                 OutFile = xstrdup (CfgSVal);
103                 CfgNextTok ();
104                 break;
105
106             case CFGTOK_PAGELENGTH:
107                 CfgNextTok ();
108                 CfgAssureInt ();
109                 if (CfgIVal != -1) {
110                     CfgRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
111                 }
112                 PageLength = CfgIVal;
113                 CfgNextTok ();
114                 break;
115         }
116
117         /* Directive is followed by a semicolon */
118         CfgConsumeSemi ();
119
120     }
121
122     /* Consume the closing brace */
123     CfgConsumeRCurly ();
124 }
125
126
127
128 static void RangeSection (void)
129 /* Parse a range section */
130 {
131     static const IdentTok RangeDefs[] = {
132         {   "START",            CFGTOK_START    },
133         {   "END",              CFGTOK_END      },
134         {   "TYPE",             CFGTOK_TYPE     },
135     };
136
137     static const IdentTok TypeDefs[] = {
138         {   "CODE",             CFGTOK_CODE     },
139         {   "BYTETABLE",        CFGTOK_BYTETAB  },
140         {   "WORDTABLE",        CFGTOK_WORDTAB  },
141         {   "DWORDTABLE",       CFGTOK_DWORDTAB },
142         {   "ADDRTABLE",        CFGTOK_ADDRTAB  },
143         {   "RTSTABLE",         CFGTOK_RTSTAB   },
144     };
145
146
147     /* Which values did we get? */
148     enum {
149         tNone   = 0x00,
150         tStart  = 0x01,
151         tEnd    = 0x02,
152         tType   = 0x04,
153         tAll    = 0x07
154     } Needed = tNone;
155
156     /* Locals - initialize to avoid gcc warnings */
157     unsigned Start      = 0;
158     unsigned End        = 0;
159     unsigned char Type  = 0;
160
161     /* Skip the token */
162     CfgNextTok ();
163
164     /* Expect the opening curly brace */
165     CfgConsumeLCurly ();
166
167     /* Look for section tokens */
168     while (CfgTok != CFGTOK_RCURLY) {
169
170         /* Convert to special token */
171         CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
172
173         /* Look at the token */
174         switch (CfgTok) {
175
176             case CFGTOK_START:
177                 CfgNextTok ();
178                 CfgAssureInt ();
179                 CfgRangeCheck (0x0000, 0xFFFF);
180                 Start = CfgIVal;
181                 Needed |= tStart;
182                 CfgNextTok ();
183                 break;
184
185             case CFGTOK_END:
186                 CfgNextTok ();
187                 CfgAssureInt ();
188                 CfgRangeCheck (0x0000, 0xFFFF);
189                 End = CfgIVal;
190                 Needed |= tEnd;
191                 CfgNextTok ();
192                 break;
193
194             case CFGTOK_TYPE:
195                 CfgNextTok ();
196                 CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
197                 switch (CfgTok) {
198                     case CFGTOK_CODE:           Type = atCode;          break;
199                     case CFGTOK_BYTETAB:        Type = atByteTab;       break;
200                     case CFGTOK_WORDTAB:        Type = atWordTab;       break;
201                     case CFGTOK_DWORDTAB:       Type = atDWordTab;      break;
202                     case CFGTOK_ADDRTAB:        Type = atAddrTab;       break;
203                     case CFGTOK_RTSTAB:         Type = atRtsTab;        break;
204                 }
205                 Needed |= tType;
206                 CfgNextTok ();
207                 break;
208         }
209
210         /* Directive is followed by a semicolon */
211         CfgConsumeSemi ();
212
213     }
214
215     /* Did we get all required values? */
216     if (Needed != tAll) {
217         Error ("Required values missing from this section");
218     }
219
220     /* Start must be less than end */
221     if (Start > End) {
222         Error ("Start value must not be greater than end value");
223     }
224
225     /* Set the range */
226     MarkRange (Start, End, Type);
227
228     /* Consume the closing brace */
229     CfgConsumeRCurly ();
230 }
231
232
233
234 static void LabelSection (void)
235 /* Parse a label section */
236 {
237     static const IdentTok Globals[] = {
238         {   "INPUTNAMEL",       CFGTOK_INPUTNAME        },
239         {   "OUTPUTNAME",       CFGTOK_OUTPUTNAME       },
240         {   "PAGELENGTH",       CFGTOK_PAGELENGTH       },
241     };
242
243     /* Skip the token */
244     CfgNextTok ();
245
246     /* Expect the opening curly brace */
247     CfgConsumeLCurly ();
248
249     /* Look for section tokens */
250     while (CfgTok != CFGTOK_RCURLY) {
251
252
253     }
254
255     /* Consume the closing brace */
256     CfgConsumeRCurly ();
257 }
258
259
260
261 static void CfgParse (void)
262 /* Parse the config file */
263 {
264     static const IdentTok Globals[] = {
265         {   "GLOBAL",   CFGTOK_GLOBAL   },
266         {   "RANGE",    CFGTOK_RANGE    },
267         {   "LABEL",    CFGTOK_LABEL    },
268     };
269
270     while (CfgTok != CFGTOK_EOF) {
271
272         /* Convert an identifier into a token */
273         CfgSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive");
274
275         /* Check the token */
276         switch (CfgTok) {
277
278             case CFGTOK_GLOBAL:
279                 GlobalSection ();
280                 break;
281
282             case CFGTOK_RANGE:
283                 RangeSection ();
284                 break;
285
286             case CFGTOK_LABEL:
287                 LabelSection ();
288                 break;
289
290         }
291
292         /* Semicolon expected */
293         CfgConsumeSemi ();
294     }
295 }
296
297
298
299 void CfgRead (void)
300 /* Read the configuration if a configuration file exists */
301 {
302     /* Check if we have a config file given */
303     if (!CfgAvail() || access (CfgGetName(), 0) != 0) {
304         /* No name given or file not found */
305         return;
306     }
307
308     /* Open the config file */
309     CfgOpenInput ();
310
311     /* Parse the config file */
312     CfgParse ();
313
314     /* Close the file */
315     CfgCloseInput ();
316 }
317
318
319
320
321
322