1 /*****************************************************************************/
5 /* Disassembler configuration file handling */
9 /* (C) 2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
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 /*****************************************************************************/
38 /* Microsoft compiler */
57 /*****************************************************************************/
59 /*****************************************************************************/
63 static void GlobalSection (void)
64 /* Parse a global section */
66 static const IdentTok GlobalDefs[] = {
67 { "INPUTNAME", CFGTOK_INPUTNAME },
68 { "OUTPUTNAME", CFGTOK_OUTPUTNAME },
69 { "PAGELENGTH", CFGTOK_PAGELENGTH },
75 /* Expect the opening curly brace */
78 /* Look for section tokens */
79 while (CfgTok != CFGTOK_RCURLY) {
81 /* Convert to special token */
82 CfgSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive");
84 /* Look at the token */
87 case CFGTOK_INPUTNAME:
91 CfgError ("Input file name already given");
93 InFile = xstrdup (CfgSVal);
97 case CFGTOK_OUTPUTNAME:
101 CfgError ("Output file name already given");
103 OutFile = xstrdup (CfgSVal);
107 case CFGTOK_PAGELENGTH:
111 CfgRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
113 PageLength = CfgIVal;
118 /* Directive is followed by a semicolon */
123 /* Consume the closing brace */
129 static void RangeSection (void)
130 /* Parse a range section */
132 static const IdentTok RangeDefs[] = {
133 { "START", CFGTOK_START },
134 { "END", CFGTOK_END },
135 { "TYPE", CFGTOK_TYPE },
138 static const IdentTok TypeDefs[] = {
139 { "CODE", CFGTOK_CODE },
140 { "BYTETABLE", CFGTOK_BYTETAB },
141 { "WORDTABLE", CFGTOK_WORDTAB },
142 { "DWORDTABLE", CFGTOK_DWORDTAB },
143 { "ADDRTABLE", CFGTOK_ADDRTAB },
144 { "RTSTABLE", CFGTOK_RTSTAB },
148 /* Which values did we get? */
157 /* Locals - initialize to avoid gcc warnings */
160 unsigned char Type = 0;
165 /* Expect the opening curly brace */
168 /* Look for section tokens */
169 while (CfgTok != CFGTOK_RCURLY) {
171 /* Convert to special token */
172 CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
174 /* Look at the token */
180 CfgRangeCheck (0x0000, 0xFFFF);
189 CfgRangeCheck (0x0000, 0xFFFF);
197 CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
199 case CFGTOK_CODE: Type = atCode; break;
200 case CFGTOK_BYTETAB: Type = atByteTab; break;
201 case CFGTOK_WORDTAB: Type = atWordTab; break;
202 case CFGTOK_DWORDTAB: Type = atDWordTab; break;
203 case CFGTOK_ADDRTAB: Type = atAddrTab; break;
204 case CFGTOK_RTSTAB: Type = atRtsTab; break;
211 /* Directive is followed by a semicolon */
216 /* Did we get all required values? */
217 if (Needed != tAll) {
218 CfgError ("Required values missing from this section");
221 /* Start must be less than end */
223 CfgError ("Start value must not be greater than end value");
227 MarkRange (Start, End, Type);
229 /* Consume the closing brace */
235 static void LabelSection (void)
236 /* Parse a label section */
238 static const IdentTok LabelDefs[] = {
239 { "NAME", CFGTOK_NAME },
240 { "ADDR", CFGTOK_ADDR },
241 { "SIZE", CFGTOK_SIZE },
244 /* Locals - initialize to avoid gcc warnings */
252 /* Expect the opening curly brace */
255 /* Look for section tokens */
256 while (CfgTok != CFGTOK_RCURLY) {
258 /* Convert to special token */
259 CfgSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
261 /* Look at the token */
267 CfgError ("Name already given");
270 if (CfgSVal[0] == '\0') {
271 CfgError ("Name may not be empty");
273 Name = xstrdup (CfgSVal);
280 CfgError ("Value already given");
283 CfgRangeCheck (0, 0xFFFF);
291 CfgError ("Size already given");
294 CfgRangeCheck (1, 0x10000);
301 /* Directive is followed by a semicolon */
305 /* Did we get the necessary data */
307 CfgError ("Label name is missing");
310 CfgError ("Label value is missing");
316 if (Value + Size > 0x10000) {
317 CfgError ("Invalid size (address out of range)");
319 if (HaveLabel ((unsigned) Value)) {
320 CfgError ("Label for address $%04lX already defined", Value);
323 /* Define the label */
324 AddLabel ((unsigned) Value, atExtLabel, Name);
326 /* Define dependent labels if necessary */
330 /* Allocate memory for the dependent label names */
331 unsigned NameLen = strlen (Name);
332 char* DepName = xmalloc (NameLen + 7);
333 char* DepOffs = DepName + NameLen + 1;
335 /* Copy the original name into the buffer */
336 memcpy (DepName, Name, NameLen);
337 DepName[NameLen] = '+';
339 /* Define the labels */
340 for (Offs = 1; Offs < (unsigned) Size; ++Offs) {
341 sprintf (DepOffs, "%u", Offs);
342 AddLabel ((unsigned) Value+Offs, atDepLabel, DepName);
345 /* Free the name buffer */
349 /* Delete the dynamically allocated memory for Name */
352 /* Consume the closing brace */
358 static void CfgParse (void)
359 /* Parse the config file */
361 static const IdentTok Globals[] = {
362 { "GLOBAL", CFGTOK_GLOBAL },
363 { "RANGE", CFGTOK_RANGE },
364 { "LABEL", CFGTOK_LABEL },
367 while (CfgTok != CFGTOK_EOF) {
369 /* Convert an identifier into a token */
370 CfgSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive");
372 /* Check the token */
389 /* Semicolon expected */
397 /* Read the configuration if a configuration file exists */
399 /* Check if we have a config file given */
400 if (!CfgAvail() || access (CfgGetName(), 0) != 0) {
401 /* No name given or file not found */
405 /* Open the config file */
408 /* Parse the config file */