Skip to content

Commit c197d69

Browse files
committed
Compiler: simplify argument parsing, add -Dxxx for features
* add `unknown_option()` to factor error handling * simplify option parsing, add `argarg` for options with an arguments * add `-DFeature` to define features from the command line * simplify `Compiler.addFeature()`: feature values are not supported yet and could be specified as `Feature=value` later * simplify Makefile for bootstrap phases
1 parent e80b1d4 commit c197d69

File tree

4 files changed

+57
-44
lines changed

4 files changed

+57
-44
lines changed

Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@ c2c: $(C2C)
2626
@$(C2C) --version
2727

2828
$(C2C): output/bootstrap/bootstrap $(C2C_DEPS)
29-
@echo "---- running (bootstrapped$(C2FLAGS)) c2c ----"
30-
@output/bootstrap/bootstrap c2c $(C2FLAGS) --fast --noplugins
31-
@mv output/c2c/c2c output/bootstrap/c2c
32-
@echo "---- running c2c (no plugins$(C2FLAGS)) ----"
33-
@output/bootstrap/c2c $(C2FLAGS) --noplugins --fast c2c $(PLUGINS)
29+
@echo "---- running bootstrap$(C2FLAGS) c2c ----"
30+
@output/bootstrap/bootstrap $(C2FLAGS) c2c -o c2c-bootstrap --fast --noplugins
31+
@echo "---- running c2c-bootstrap (no plugins$(C2FLAGS)) ----"
32+
@output/c2c-bootstrap/c2c-bootstrap $(C2FLAGS) --fast --noplugins c2c $(PLUGINS)
3433
@./install_plugins.sh
3534
@echo "---- running c2c (optimized with plugins$(C2FLAGS)) ----"
3635
@output/c2c/c2c $(C2FLAGS)

common/build_target.c2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public fn u32 Target.numAsmFiles(const Target* t) { return t.asm_file_count; }
165165
public fn const string_list.List* Target.getFeatures(const Target* t) { return &t.features; }
166166

167167
public fn void Target.addFeature(Target* t, u32 feature) {
168+
// TODO: handle value
168169
t.features.add(feature);
169170
}
170171

compiler/compiler.c2

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,13 @@ public fn void build(string_pool.Pool* auxPool,
9494
build_file.Info* build_info, // can be nil
9595
build_target.Target* target,
9696
const Options* opts,
97+
string_list.List* features,
9798
PluginHandler* pluginHandler)
9899
{
99100
Compiler c = {}
100101
plugin_info.Info info = {}
101102

102-
c.build(auxPool, sm, diags, build_info, target, opts, pluginHandler, &info);
103+
c.build(auxPool, sm, diags, build_info, target, opts, features, pluginHandler, &info);
103104

104105
if (opts.print_reports) {
105106
c.sm.report(opts.print_reports > 1);
@@ -212,6 +213,7 @@ fn void Compiler.build(Compiler* c,
212213
build_file.Info* build_info, // can be nil
213214
build_target.Target* target,
214215
const Options* opts,
216+
string_list.List* features,
215217
PluginHandler* pluginHandler,
216218
plugin_info.Info* info)
217219
{
@@ -297,15 +299,19 @@ fn void Compiler.build(Compiler* c,
297299
c.addGlobalDefine("SYSTEM", c.targetInfo.getSystemName());
298300
c.addGlobalDefine("ARCH", c.targetInfo.getArchName());
299301
if (c.targetInfo.intWidth == 64) {
300-
c.addFeature("ARCH_64BIT", "1");
302+
c.addFeature("ARCH_64BIT");
301303
} else {
302-
c.addFeature("ARCH_32BIT", "1");
304+
c.addFeature("ARCH_32BIT");
303305
}
304-
if (opts.asan) c.addFeature("__ASAN__", "1");
305-
if (opts.msan) c.addFeature("__MSAN__", "1");
306-
if (opts.ubsan) c.addFeature("__UBSAN__", "1");
306+
if (opts.asan) c.addFeature("__ASAN__");
307+
if (opts.msan) c.addFeature("__MSAN__");
308+
if (opts.ubsan) c.addFeature("__UBSAN__");
307309

308-
c.addFeature("USE_NATIVE_CTYPES", "1");
310+
for (u32 i = 0; i < features.length(); i++) {
311+
c.addFeature(features.get(i));
312+
}
313+
314+
c.addFeature("USE_NATIVE_CTYPES");
309315

310316
target.addLib(c.auxPool.add("c2", 2, true), false);
311317

@@ -667,20 +673,19 @@ fn void Compiler.checkMain(Compiler* c) {
667673
}
668674
}
669675

670-
fn void Compiler.addFeature(Compiler* c, const char* str, const char* value) {
671-
// TODO: handle value
676+
fn void Compiler.addFeature(Compiler* c, const char* str) {
672677
c.target.addFeature(c.auxPool.addStr(str, true));
673678
}
674679

675680
fn void Compiler.addGlobalDefine(Compiler* c, const char* prefix, const char* tail) {
676681
char[32] tmp;
677-
stdio.snprintf(tmp, 32, "%s_%s", prefix, tail);
682+
stdio.snprintf(tmp, elemsof(tmp), "%s_%s", prefix, tail);
678683
for (usize i = 0; tmp[i]; i++) {
679684
u8 ch = (u8)tmp[i];
680685
tmp[i] = (ch == '-') ? '_' : (char)ctype.toupper(ch);
681686
}
682687

683-
c.addFeature(tmp, "1");
688+
c.addFeature(tmp);
684689
}
685690

686691
// NOTE: paths are not 0-terminated

compiler/main.c2

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,20 @@ type Options struct {
5656
const char* output_name;
5757
string_list.List targets;
5858
string_list.List files;
59+
string_list.List features;
5960
}
6061

6162
fn void Options.init(Options* opts, string_pool.Pool* pool) {
6263
memset(opts, 0, sizeof(Options));
6364
opts.targets.init(pool);
6465
opts.files.init(pool);
66+
opts.features.init(pool);
6567
}
6668

6769
fn void Options.free(Options *opts) {
6870
opts.targets.free();
6971
opts.files.free();
72+
opts.features.free();
7073
}
7174

7275
fn void write_file_or_die(const char* filename, string_buffer.Buf* buf) {
@@ -176,6 +179,7 @@ const char[] Usage_help =
176179
" -A print Library ASTs\n"
177180
" -b [file] use specified build file\n"
178181
" -d [dir] change to [dir] first\n"
182+
" -Dfeature define global feature\n"
179183
" -h print this help\n"
180184
" -i use IR backend\n"
181185
" -I use IR backend and print generated IR\n"
@@ -216,8 +220,12 @@ fn void missing_arg(const char* option) {
216220
exit(EXIT_FAILURE);
217221
}
218222

219-
fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
220-
const char* arg = argv[i];
223+
fn void unknown_option(const char* option) {
224+
console.error("c2c: unknown option: '%s'", option);
225+
exit(EXIT_FAILURE);
226+
}
227+
228+
fn i32 parse_long_opt(const char* arg, i32 i, i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
221229
switch (arg+2) {
222230
case "I2":
223231
opts.use_ir_backend = true;
@@ -227,9 +235,8 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
227235
comp_opts.check_only = true;
228236
break;
229237
case "create":
230-
if (i==argc-1) missing_arg(arg);
231-
i++;
232-
create_project(argv[i]);
238+
if (i >= argc) missing_arg(arg);
239+
create_project(argv[i++]);
233240
break;
234241
case "fast":
235242
comp_opts.fast_build = true;
@@ -250,9 +257,8 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
250257
opts.show_plugins = true;
251258
break;
252259
case "target":
253-
if (i==argc-1) missing_arg(arg);
254-
i++;
255-
comp_opts.target_triple = argv[i];
260+
if (i >= argc) missing_arg(arg);
261+
comp_opts.target_triple = argv[i++];
256262
break;
257263
case "targets":
258264
opts.show_targets = true;
@@ -276,22 +282,28 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
276282
print_version();
277283
exit(EXIT_SUCCESS);
278284
default:
279-
console.error("c2c: unknown option: %s", arg);
280-
exit(EXIT_FAILURE);
285+
unknown_option(arg);
286+
break;
281287
}
282288
return i;
283289
}
284290

285291
fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
286-
for (i32 i=1; i<argc; i++) {
287-
const char* arg = argv[i];
292+
for (i32 i = 1; i < argc;) {
293+
const char* arg = argv[i++];
288294
if (arg[0] == '-') {
289295
if (arg[1] == '-') {
290-
i = parse_long_opt(i, argc, argv, comp_opts, opts);
296+
i = parse_long_opt(arg, i, argc, argv, comp_opts, opts);
291297
} else {
292-
if (strlen(arg) != 2) {
293-
console.error("c2c: unknown option '%s'", arg);
294-
exit(EXIT_FAILURE);
298+
const char *argarg = nil;
299+
if (memchr("Ddbo", arg[1], 4)) { // needs argument
300+
argarg = &arg[2];
301+
if (!*argarg) {
302+
if (i >= argc) missing_arg(arg);
303+
argarg = argv[i++];
304+
}
305+
} else if (strlen(arg) != 2) {
306+
unknown_option(arg);
295307
}
296308
switch (arg[1]) {
297309
case '0': // 'hidden' feature, print AST early after parsing, then quit
@@ -300,6 +312,9 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
300312
case 'A':
301313
comp_opts.print_lib_ast = true;
302314
break;
315+
case 'D':
316+
opts.features.addStr(argarg);
317+
break;
303318
case 'I':
304319
opts.use_ir_backend = true;
305320
comp_opts.print_ir = true;
@@ -314,14 +329,10 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
314329
comp_opts.print_ast = true;
315330
break;
316331
case 'b':
317-
if (i==argc-1) missing_arg(arg);
318-
i++;
319-
opts.build_file = argv[i];
332+
opts.build_file = argarg;
320333
break;
321334
case 'd':
322-
if (i==argc-1) missing_arg(arg);
323-
i++;
324-
opts.other_dir = argv[i];
335+
opts.other_dir = argarg;
325336
break;
326337
case '?':
327338
case 'h':
@@ -334,9 +345,7 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
334345
comp_opts.print_modules = true;
335346
break;
336347
case 'o':
337-
if (i==argc-1) missing_arg(arg);
338-
i++;
339-
opts.output_name = argv[i];
348+
opts.output_name = argarg;
340349
break;
341350
case 'r':
342351
comp_opts.print_reports += 1;
@@ -354,8 +363,7 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
354363
opts.force_warnings = true;
355364
break;
356365
default:
357-
console.error("c2c: unknown option '-%c'", arg[1]);
358-
exit(EXIT_FAILURE);
366+
unknown_option(arg);
359367
break;
360368
}
361369
}
@@ -592,7 +600,7 @@ fn bool Context.build_target(Context* c,
592600
}
593601
}
594602

595-
compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.pluginHandler);
603+
compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.opts.features, &c.pluginHandler);
596604

597605
// TODO unload target-specific plugins?
598606
// TODO fix build_file

0 commit comments

Comments
 (0)