comparison lwasm/main.c @ 151:427e268e876b

renamed src to lwasm to better reflect its purpose
author lost
date Fri, 30 Jan 2009 04:01:55 +0000
parents src/main.c@0ee5f65bccf9
children 833d392fec82
comparison
equal deleted inserted replaced
150:f0881c115010 151:427e268e876b
1 /*
2 main.c
3 Copyright © 2008 William Astle
4
5 This file is part of LWASM.
6
7 LWASM is free software: you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation, either version 3 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21 Implements the program startup code
22
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <argp.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #include "lwasm.h"
35
36 // external declarations
37 extern void lwasm_pass1(asmstate_t *as);
38 extern void lwasm_pass2(asmstate_t *as);
39 extern void lwasm_list(asmstate_t *as);
40 extern void lwasm_output(asmstate_t *as);
41 extern void pseudo_pragma_real(asmstate_t *as, lwasm_line_t *cl, char **optr, int error);
42
43 // command line option handling
44 const char *argp_program_version = "LWASM from " PACKAGE_STRING;
45 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
46
47 static error_t parse_opts(int key, char *arg, struct argp_state *state)
48 {
49 asmstate_t *as = state -> input;
50 char *p;
51
52 switch (key)
53 {
54 case 'o':
55 // output
56 if (as -> outfile)
57 {
58 }
59 as -> outfile = arg;
60 break;
61
62 case 'd':
63 // debug
64 debug_level++;
65 break;
66
67 case 'l':
68 // list
69 if (arg)
70 as -> listfile = arg;
71 else
72 as -> listfile = "-";
73 break;
74
75 case 'b':
76 // decb output
77 as -> outformat = OUTPUT_DECB;
78 break;
79
80 case 'r':
81 // raw binary output
82 as -> outformat = OUTPUT_RAW;
83 break;
84
85 case 0x100:
86 // proprietary object format
87 as -> outformat = OUTPUT_OBJ;
88 break;
89
90 case 'f':
91 // output format
92 if (!strcasecmp(arg, "decb"))
93 as -> outformat = OUTPUT_DECB;
94 else if (!strcasecmp(arg, "raw"))
95 as -> outformat = OUTPUT_RAW;
96 else if (!strcasecmp(arg, "obj"))
97 as -> outformat = OUTPUT_OBJ;
98 else
99 {
100 fprintf(stderr, "Invalid output format: %s\n", arg);
101 exit(1);
102 }
103 break;
104
105 case 'p':
106 // pragmas
107 p = arg;
108 pseudo_pragma_real(as, NULL, &p, 2);
109 if (!p)
110 {
111 fprintf(stderr, "Invalid pragma string: %s\n", arg);
112 exit(1);
113 }
114 break;
115
116 case ARGP_KEY_END:
117 // done; sanity check
118 if (!as -> outfile)
119 as -> outfile = "a.out";
120 break;
121
122 case ARGP_KEY_ARG:
123 // non-option arg
124 if (as -> infile)
125 argp_usage(state);
126 as -> infile = arg;
127 break;
128
129 default:
130 return ARGP_ERR_UNKNOWN;
131 }
132 return 0;
133 }
134
135 static struct argp_option options[] =
136 {
137 { "output", 'o', "FILE", 0,
138 "Output to FILE"},
139 { "debug", 'd', 0, 0,
140 "Set debug mode"},
141 { "format", 'f', "TYPE", 0,
142 "Select output format: decb, raw, obj"},
143 { "list", 'l', "FILE", OPTION_ARG_OPTIONAL,
144 "Generate list [to FILE]"},
145 { "decb", 'b', 0, 0,
146 "Generate DECB .bin format output, equivalent of --format=decb"},
147 { "raw", 'r', 0, 0,
148 "Generate raw binary format output, equivalent of --format=raw"},
149 { "obj", 0x100, 0, 0,
150 "Generate proprietary object file format for later linking, equivalent of --format=obj" },
151 { "pragma", 'p', "PRAGMA", 0,
152 "Set an assembler pragma to any value understood by the \"pragma\" pseudo op"},
153 { 0 }
154 };
155
156 static struct argp argp =
157 {
158 options,
159 parse_opts,
160 "<input file>",
161 "LWASM, a HD6309 and MC6809 cross-assembler"
162 };
163
164 // main function; parse command line, set up assembler state, and run the
165 // assembler on the first file
166 int main(int argc, char **argv)
167 {
168 // assembler state
169 asmstate_t asmstate = { 0 };
170
171 argp_parse(&argp, argc, argv, 0, 0, &asmstate);
172
173 if (!asmstate.infile)
174 {
175 fprintf(stderr, "No input files specified.\n");
176 exit(1);
177 }
178
179 /* pass 1 - collect the symbols and assign addresses where possible */
180 /* pass 1 also resolves included files, etc. */
181 /* that means files are read exactly once unless included multiple times */
182 lwasm_pass1(&asmstate);
183
184 // pass 2: actually generate the code; if any phasing errors appear
185 // at this stage, we have a bug
186 lwasm_pass2(&asmstate);
187
188 // now make a pretty listing
189 lwasm_list(&asmstate);
190
191 // now write the code out to the output file
192 lwasm_output(&asmstate);
193
194 if (asmstate.errorcount > 0)
195 exit(1);
196
197 exit(0);
198 }
199