Mercurial > hg-old > index.cgi
annotate lwasm/main.c @ 388:8991eb507d2d
Added missing arg-nonnull.h ??? file to repo
author | lost@l-w.ca |
---|---|
date | Wed, 14 Jul 2010 20:17:57 -0600 |
parents | a741d2e4869f |
children | 027d7fbcdcfc |
rev | line source |
---|---|
323 | 1 /* |
2 main.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <argp.h> | |
25 #include <stdio.h> | |
26 #include <stdlib.h> | |
27 | |
329 | 28 #include <lw_alloc.h> |
325 | 29 #include <lw_string.h> |
30 #include <lw_stringlist.h> | |
335 | 31 #include <lw_expr.h> |
325 | 32 |
323 | 33 #include "lwasm.h" |
330 | 34 #include "input.h" |
323 | 35 |
352 | 36 extern int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr); |
325 | 37 |
323 | 38 /* command line option handling */ |
39 const char *argp_program_version = "lwasm from " PACKAGE_STRING; | |
40 const char *argp_program_bug_address = PACKAGE_BUGREPORT; | |
41 char *program_name; | |
42 | |
43 static struct argp_option options[] = | |
44 { | |
45 { "output", 'o', "FILE", 0, "Output to FILE"}, | |
372
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
46 { "debug", 'd', "LEVEL", OPTION_ARG_OPTIONAL, "Set debug mode"}, |
323 | 47 { "format", 'f', "TYPE", 0, "Select output format: decb, raw, obj, os9"}, |
48 { "list", 'l', "FILE", OPTION_ARG_OPTIONAL, "Generate list [to FILE]"}, | |
49 { "decb", 'b', 0, 0, "Generate DECB .bin format output, equivalent of --format=decb"}, | |
50 { "raw", 'r', 0, 0, "Generate raw binary format output, equivalent of --format=raw"}, | |
51 { "obj", 0x100, 0, 0, "Generate proprietary object file format for later linking, equivalent of --format=obj" }, | |
52 { "depend", 0x101, 0, 0, "Output a dependency list to stdout; do not do any actual output though assembly is completed as usual" }, | |
53 { "pragma", 'p', "PRAGMA", 0, "Set an assembler pragma to any value understood by the \"pragma\" pseudo op"}, | |
54 { "6809", '9', 0, 0, "Set assembler to 6809 only mode" }, | |
55 { "6309", '3', 0, 0, "Set assembler to 6309 mode (default)" }, | |
56 { "includedir", 'I', "PATH", 0, "Add entry to include path" }, | |
57 { 0 } | |
58 }; | |
59 | |
60 | |
61 static error_t parse_opts(int key, char *arg, struct argp_state *state) | |
62 { | |
63 asmstate_t *as = state -> input; | |
64 | |
65 switch (key) | |
66 { | |
67 case 'I': | |
325 | 68 lw_stringlist_addstring(as -> include_list, arg); |
69 break; | |
70 | |
323 | 71 case 'o': |
325 | 72 if (as -> output_file) |
73 lw_free(as -> output_file); | |
74 as -> output_file = lw_strdup(arg); | |
75 break; | |
76 | |
323 | 77 case 'd': |
372
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
78 if (!arg) |
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
79 as -> debug_level = 50; |
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
80 else |
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
81 as -> debug_level = atoi(arg); |
323 | 82 break; |
83 | |
84 case 'l': | |
325 | 85 if (as -> list_file) |
86 lw_free(as -> list_file); | |
87 if (!arg) | |
88 as -> list_file = NULL; | |
89 else | |
90 as -> list_file = lw_strdup(arg); | |
91 as -> flags |= FLAG_LIST; | |
92 break; | |
93 | |
323 | 94 case 'b': |
95 as -> output_format = OUTPUT_DECB; | |
96 break; | |
97 | |
98 case 'r': | |
99 as -> output_format = OUTPUT_RAW; | |
100 break; | |
101 | |
102 case 0x100: | |
103 as -> output_format = OUTPUT_OBJ; | |
104 break; | |
105 | |
106 case 0x101: | |
325 | 107 as -> flags |= FLAG_DEPEND; |
108 break; | |
109 | |
323 | 110 case 'f': |
111 if (!strcasecmp(arg, "decb")) | |
112 as -> output_format = OUTPUT_DECB; | |
113 else if (!strcasecmp(arg, "raw")) | |
114 as -> output_format = OUTPUT_RAW; | |
115 else if (!strcasecmp(arg, "obj")) | |
116 as -> output_format = OUTPUT_OBJ; | |
117 else if (!strcasecmp(arg, "os9")) | |
118 { | |
325 | 119 as -> pragmas |= PRAGMA_DOLLARNOTLOCAL; |
323 | 120 as -> output_format = OUTPUT_OS9; |
121 } | |
122 else | |
123 { | |
124 fprintf(stderr, "Invalid output format: %s\n", arg); | |
125 exit(1); | |
126 } | |
127 break; | |
128 | |
129 case 'p': | |
352 | 130 if (parse_pragma_string(as, arg, 0) == 0) |
325 | 131 { |
132 fprintf(stderr, "Unrecognized pragma string: %s\n", arg); | |
133 exit(1); | |
134 } | |
135 break; | |
136 | |
323 | 137 case '9': |
138 as -> target = TARGET_6809; | |
139 break; | |
140 | |
141 case '3': | |
142 as -> target = TARGET_6309; | |
143 break; | |
144 | |
145 case ARGP_KEY_END: | |
146 break; | |
147 | |
148 case ARGP_KEY_ARG: | |
325 | 149 lw_stringlist_addstring(as -> input_files, arg); |
323 | 150 break; |
151 | |
152 default: | |
153 return ARGP_ERR_UNKNOWN; | |
154 } | |
155 return 0; | |
156 } | |
157 | |
158 static struct argp argp = | |
159 { | |
160 options, | |
161 parse_opts, | |
162 "<input file>", | |
163 "LWASM, a HD6309 and MC6809 cross-assembler" | |
164 }; | |
165 | |
166 /* | |
167 main function; parse command line, set up assembler state, and run the | |
168 assembler on the first file | |
169 */ | |
332 | 170 extern void do_pass1(asmstate_t *as); |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
352
diff
changeset
|
171 extern void do_pass2(asmstate_t *as); |
364 | 172 extern void do_pass3(asmstate_t *as); |
365 | 173 extern void do_pass4(asmstate_t *as); |
367 | 174 extern void do_pass5(asmstate_t *as); |
175 extern void do_pass6(asmstate_t *as); | |
368 | 176 extern void do_pass7(asmstate_t *as); |
374 | 177 extern void do_output(asmstate_t *as); |
383
848d3cca8078
Fixed imm8 to actually use expression and also fixed gen mode to respect > and <
lost@starbug
parents:
374
diff
changeset
|
178 extern void do_list(asmstate_t *as); |
346
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
179 extern lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
180 extern lw_expr_t lwasm_evaluate_var(char *var, void *priv); |
a82c55070624
Added expression parsing infrastructure and misc fixes
lost@starbug
parents:
345
diff
changeset
|
181 extern lw_expr_t lwasm_parse_term(char **p, void *priv); |
364 | 182 |
183 struct passlist_s | |
184 { | |
185 char *passname; | |
186 void (*fn)(asmstate_t *as); | |
385 | 187 int fordep; |
364 | 188 } passlist[] = { |
385 | 189 { "parse", do_pass1, 1 }, |
364 | 190 { "symcheck", do_pass2 }, |
191 { "resolve1", do_pass3 }, | |
365 | 192 { "resolve2", do_pass4 }, |
367 | 193 { "addressresolve", do_pass5 }, |
194 { "finalize", do_pass6 }, | |
368 | 195 { "emit", do_pass7 }, |
364 | 196 { NULL, NULL } |
197 }; | |
198 | |
370 | 199 |
323 | 200 int main(int argc, char **argv) |
201 { | |
364 | 202 int passnum; |
203 | |
323 | 204 /* assembler state */ |
205 asmstate_t asmstate = { 0 }; | |
325 | 206 program_name = argv[0]; |
323 | 207 |
337 | 208 lw_expr_set_special_handler(lwasm_evaluate_special); |
209 lw_expr_set_var_handler(lwasm_evaluate_var); | |
370 | 210 lw_expr_set_term_parser(lwasm_parse_term); |
337 | 211 |
325 | 212 /* initialize assembler state */ |
329 | 213 asmstate.include_list = lw_stringlist_create(); |
325 | 214 asmstate.input_files = lw_stringlist_create(); |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
342
diff
changeset
|
215 asmstate.nextcontext = 1; |
325 | 216 |
217 /* parse command line arguments */ | |
323 | 218 argp_parse(&argp, argc, argv, 0, 0, &asmstate); |
219 | |
328 | 220 if (!asmstate.output_file) |
221 { | |
222 asmstate.output_file = lw_strdup("a.out"); | |
223 } | |
224 | |
330 | 225 input_init(&asmstate); |
226 | |
364 | 227 for (passnum = 0; passlist[passnum].fn; passnum++) |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
352
diff
changeset
|
228 { |
385 | 229 if ((asmstate.flags & FLAG_DEPEND) && passlist[passnum].fordep == 0) |
230 continue; | |
372
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
231 debug_message(&asmstate, 50, "Doing pass %d (%s)\n", passnum, passlist[passnum].passname); |
364 | 232 (passlist[passnum].fn)(&asmstate); |
372
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
233 debug_message(&asmstate, 50, "After pass %d (%s)\n", passnum, passlist[passnum].passname); |
90de73ba0cac
Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
lost@starbug
parents:
370
diff
changeset
|
234 dump_state(&asmstate); |
364 | 235 |
236 if (asmstate.errorcount > 0) | |
237 { | |
238 lwasm_show_errors(&asmstate); | |
239 exit(1); | |
240 } | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
352
diff
changeset
|
241 } |
384 | 242 |
243 if (asmstate.flags & FLAG_DEPEND) | |
244 { | |
245 // output dependencies | |
246 char *n; | |
247 | |
248 while (n = lw_stack_pop(asmstate.includelist)) | |
249 { | |
250 fprintf(stdout, "%s\n", n); | |
251 lw_free(n); | |
252 } | |
253 } | |
254 else | |
255 { | |
256 debug_message(&asmstate, 50, "Doing output"); | |
257 do_output(&asmstate); | |
258 } | |
374 | 259 |
260 debug_message(&asmstate, 50, "Done assembly"); | |
383
848d3cca8078
Fixed imm8 to actually use expression and also fixed gen mode to respect > and <
lost@starbug
parents:
374
diff
changeset
|
261 |
848d3cca8078
Fixed imm8 to actually use expression and also fixed gen mode to respect > and <
lost@starbug
parents:
374
diff
changeset
|
262 do_list(&asmstate); |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
263 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
264 exit(0); |
323 | 265 } |