authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-22 01:49:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-22 01:54:38-04:00
log8866bef92c8b674c2a444c94326c57984597ab05
treecfe58074556705cd98182d37886b793a0dbf88c5
parentbe2a4c42bdfdbf9130eaeee3ce66085cb862dcd1

clean up self hosted main. delete unsupported commands


4 files changed, 121 insertions(+), 459 deletions(-)

src-self-hosted/arg.zig+2-2
......@@ -168,7 +168,7 @@ pub const Args = struct {
168168 }
169169
170170 // e.g. --names value1 value2 value3
171 pub fn many(self: *Args, name: []const u8) ?[]const []const u8 {
171 pub fn many(self: *Args, name: []const u8) []const []const u8 {
172172 if (self.flags.get(name)) |entry| {
173173 switch (entry.value) {
174174 FlagArg.Many => |inner| {
......@@ -177,7 +177,7 @@ pub const Args = struct {
177177 else => @panic("attempted to retrieve flag with wrong type"),
178178 }
179179 } else {
180 return null;
180 return []const []const u8{};
181181 }
182182 }
183183};
src-self-hosted/main.zig+116-430
......@@ -26,15 +26,11 @@ const usage =
2626 \\
2727 \\Commands:
2828 \\
29 \\ build Build project from build.zig
3029 \\ build-exe [source] Create executable from source or object files
3130 \\ build-lib [source] Create library from source or object files
3231 \\ build-obj [source] Create object from source or assembly
3332 \\ fmt [source] Parse file and render in canonical zig format
34 \\ run [source] Create executable and run immediately
3533 \\ targets List available compilation targets
36 \\ test [source] Create and run a test build
37 \\ translate-c [source] Convert c code to zig code
3834 \\ version Print version number and exit
3935 \\ zen Print zen of zig and exit
4036 \\
......@@ -47,7 +43,7 @@ const Command = struct {
4743};
4844
4945pub fn main() !void {
50 var allocator = std.heap.c_allocator;
46 const allocator = std.heap.c_allocator;
5147
5248 var stdout_file = try std.io.getStdOut();
5349 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
......@@ -58,18 +54,16 @@ pub fn main() !void {
5854 stderr = &stderr_out_stream.stream;
5955
6056 const args = try os.argsAlloc(allocator);
61 defer os.argsFree(allocator, args);
57 // TODO I'm getting unreachable code here, which shouldn't happen
58 //defer os.argsFree(allocator, args);
6259
6360 if (args.len <= 1) {
61 try stderr.write("expected command argument\n\n");
6462 try stderr.write(usage);
6563 os.exit(1);
6664 }
6765
6866 const commands = []Command{
69 Command{
70 .name = "build",
71 .exec = cmdBuild,
72 },
7367 Command{
7468 .name = "build-exe",
7569 .exec = cmdBuildExe,
......@@ -86,22 +80,10 @@ pub fn main() !void {
8680 .name = "fmt",
8781 .exec = cmdFmt,
8882 },
89 Command{
90 .name = "run",
91 .exec = cmdRun,
92 },
9383 Command{
9484 .name = "targets",
9585 .exec = cmdTargets,
9686 },
97 Command{
98 .name = "test",
99 .exec = cmdTest,
100 },
101 Command{
102 .name = "translate-c",
103 .exec = cmdTranslateC,
104 },
10587 Command{
10688 .name = "version",
10789 .exec = cmdVersion,
......@@ -124,177 +106,15 @@ pub fn main() !void {
124106
125107 for (commands) |command| {
126108 if (mem.eql(u8, command.name, args[1])) {
127 try command.exec(allocator, args[2..]);
128 return;
109 return command.exec(allocator, args[2..]);
129110 }
130111 }
131112
132113 try stderr.print("unknown command: {}\n\n", args[1]);
133114 try stderr.write(usage);
115 os.exit(1);
134116}
135117
136// cmd:build ///////////////////////////////////////////////////////////////////////////////////////
137
138const usage_build =
139 \\usage: zig build <options>
140 \\
141 \\General Options:
142 \\ --help Print this help and exit
143 \\ --init Generate a build.zig template
144 \\ --build-file [file] Override path to build.zig
145 \\ --cache-dir [path] Override path to cache directory
146 \\ --verbose Print commands before executing them
147 \\ --prefix [path] Override default install prefix
148 \\
149 \\Project-Specific Options:
150 \\
151 \\ Project-specific options become available when the build file is found.
152 \\
153 \\Advanced Options:
154 \\ --build-file [file] Override path to build.zig
155 \\ --cache-dir [path] Override path to cache directory
156 \\ --verbose-tokenize Enable compiler debug output for tokenization
157 \\ --verbose-ast Enable compiler debug output for parsing into an AST
158 \\ --verbose-link Enable compiler debug output for linking
159 \\ --verbose-ir Enable compiler debug output for Zig IR
160 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
161 \\ --verbose-cimport Enable compiler debug output for C imports
162 \\
163 \\
164;
165
166const args_build_spec = []Flag{
167 Flag.Bool("--help"),
168 Flag.Bool("--init"),
169 Flag.Arg1("--build-file"),
170 Flag.Arg1("--cache-dir"),
171 Flag.Bool("--verbose"),
172 Flag.Arg1("--prefix"),
173
174 Flag.Arg1("--build-file"),
175 Flag.Arg1("--cache-dir"),
176 Flag.Bool("--verbose-tokenize"),
177 Flag.Bool("--verbose-ast"),
178 Flag.Bool("--verbose-link"),
179 Flag.Bool("--verbose-ir"),
180 Flag.Bool("--verbose-llvm-ir"),
181 Flag.Bool("--verbose-cimport"),
182};
183
184const missing_build_file =
185 \\No 'build.zig' file found.
186 \\
187 \\Initialize a 'build.zig' template file with `zig build --init`,
188 \\or build an executable directly with `zig build-exe $FILENAME.zig`.
189 \\
190 \\See: `zig build --help` or `zig help` for more options.
191 \\
192;
193
194fn cmdBuild(allocator: *Allocator, args: []const []const u8) !void {
195 var flags = try Args.parse(allocator, args_build_spec, args);
196 defer flags.deinit();
197
198 if (flags.present("help")) {
199 try stderr.write(usage_build);
200 os.exit(0);
201 }
202
203 const zig_lib_dir = try introspect.resolveZigLibDir(allocator);
204 defer allocator.free(zig_lib_dir);
205
206 const zig_std_dir = try os.path.join(allocator, zig_lib_dir, "std");
207 defer allocator.free(zig_std_dir);
208
209 const special_dir = try os.path.join(allocator, zig_std_dir, "special");
210 defer allocator.free(special_dir);
211
212 const build_runner_path = try os.path.join(allocator, special_dir, "build_runner.zig");
213 defer allocator.free(build_runner_path);
214
215 const build_file = flags.single("build-file") orelse "build.zig";
216 const build_file_abs = try os.path.resolve(allocator, ".", build_file);
217 defer allocator.free(build_file_abs);
218
219 const build_file_exists = os.File.access(allocator, build_file_abs, os.default_file_mode) catch false;
220
221 if (flags.present("init")) {
222 if (build_file_exists) {
223 try stderr.print("build.zig already exists\n");
224 os.exit(1);
225 }
226
227 // need a new scope for proper defer scope finalization on exit
228 {
229 const build_template_path = try os.path.join(allocator, special_dir, "build_file_template.zig");
230 defer allocator.free(build_template_path);
231
232 try os.copyFile(allocator, build_template_path, build_file_abs);
233 try stderr.print("wrote build.zig template\n");
234 }
235
236 os.exit(0);
237 }
238
239 if (!build_file_exists) {
240 try stderr.write(missing_build_file);
241 os.exit(1);
242 }
243
244 // TODO: Invoke build.zig entrypoint directly?
245 var zig_exe_path = try os.selfExePath(allocator);
246 defer allocator.free(zig_exe_path);
247
248 var build_args = ArrayList([]const u8).init(allocator);
249 defer build_args.deinit();
250
251 const build_file_basename = os.path.basename(build_file_abs);
252 const build_file_dirname = os.path.dirname(build_file_abs) orelse ".";
253
254 var full_cache_dir: []u8 = undefined;
255 if (flags.single("cache-dir")) |cache_dir| {
256 full_cache_dir = try os.path.resolve(allocator, ".", cache_dir, full_cache_dir);
257 } else {
258 full_cache_dir = try os.path.join(allocator, build_file_dirname, "zig-cache");
259 }
260 defer allocator.free(full_cache_dir);
261
262 const path_to_build_exe = try os.path.join(allocator, full_cache_dir, "build");
263 defer allocator.free(path_to_build_exe);
264
265 try build_args.append(path_to_build_exe);
266 try build_args.append(zig_exe_path);
267 try build_args.append(build_file_dirname);
268 try build_args.append(full_cache_dir);
269
270 var proc = try os.ChildProcess.init(build_args.toSliceConst(), allocator);
271 defer proc.deinit();
272
273 var term = try proc.spawnAndWait();
274 switch (term) {
275 os.ChildProcess.Term.Exited => |status| {
276 if (status != 0) {
277 try stderr.print("{} exited with status {}\n", build_args.at(0), status);
278 os.exit(1);
279 }
280 },
281 os.ChildProcess.Term.Signal => |signal| {
282 try stderr.print("{} killed by signal {}\n", build_args.at(0), signal);
283 os.exit(1);
284 },
285 os.ChildProcess.Term.Stopped => |signal| {
286 try stderr.print("{} stopped by signal {}\n", build_args.at(0), signal);
287 os.exit(1);
288 },
289 os.ChildProcess.Term.Unknown => |status| {
290 try stderr.print("{} encountered unknown failure {}\n", build_args.at(0), status);
291 os.exit(1);
292 },
293 }
294}
295
296// cmd:build-exe ///////////////////////////////////////////////////////////////////////////////////
297
298118const usage_build_generic =
299119 \\usage: zig build-exe <options> [file]
300120 \\ zig build-lib <options> [file]
......@@ -315,8 +135,11 @@ const usage_build_generic =
315135 \\ --output-h [file] Override generated header file path
316136 \\ --pkg-begin [name] [path] Make package available to import and push current pkg
317137 \\ --pkg-end Pop current pkg
318 \\ --release-fast Build with optimizations on and safety off
319 \\ --release-safe Build with optimizations on and safety on
138 \\ --mode [mode] Set the build mode
139 \\ debug (default) optimizations off, safety on
140 \\ release-fast optimizations on, safety off
141 \\ release-safe optimizations on, safety on
142 \\ release-small optimize for small binary, safety off
320143 \\ --static Output will be statically linked
321144 \\ --strip Exclude debug symbols
322145 \\ --target-arch [name] Specify target architecture
......@@ -367,6 +190,12 @@ const args_build_generic = []Flag{
367190 "off",
368191 "on",
369192 }),
193 Flag.Option("--mode", []const []const u8{
194 "debug",
195 "release-fast",
196 "release-safe",
197 "release-small",
198 }),
370199
371200 Flag.ArgMergeN("--assembly", 1),
372201 Flag.Arg1("--cache-dir"),
......@@ -383,8 +212,6 @@ const args_build_generic = []Flag{
383212 // NOTE: Parsed manually after initial check
384213 Flag.ArgN("--pkg-begin", 2),
385214 Flag.Bool("--pkg-end"),
386 Flag.Bool("--release-fast"),
387 Flag.Bool("--release-safe"),
388215 Flag.Bool("--static"),
389216 Flag.Bool("--strip"),
390217 Flag.Arg1("--target-arch"),
......@@ -431,16 +258,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
431258 defer flags.deinit();
432259
433260 if (flags.present("help")) {
434 try stderr.write(usage_build_generic);
261 try stdout.write(usage_build_generic);
435262 os.exit(0);
436263 }
437264
438 var build_mode = builtin.Mode.Debug;
439 if (flags.present("release-fast")) {
440 build_mode = builtin.Mode.ReleaseFast;
441 } else if (flags.present("release-safe")) {
442 build_mode = builtin.Mode.ReleaseSafe;
443 }
265 const build_mode = blk: {
266 if (flags.single("mode")) |mode_flag| {
267 if (mem.eql(u8, mode_flag, "debug")) {
268 break :blk builtin.Mode.Debug;
269 } else if (mem.eql(u8, mode_flag, "release-fast")) {
270 break :blk builtin.Mode.ReleaseFast;
271 } else if (mem.eql(u8, mode_flag, "release-safe")) {
272 break :blk builtin.Mode.ReleaseSafe;
273 } else if (mem.eql(u8, mode_flag, "release-small")) {
274 break :blk builtin.Mode.ReleaseSmall;
275 } else unreachable;
276 } else {
277 break :blk builtin.Mode.Debug;
278 }
279 };
444280
445281 const color = blk: {
446282 if (flags.single("color")) |color_flag| {
......@@ -456,20 +292,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
456292 }
457293 };
458294
459 var emit_type = Module.Emit.Binary;
460 if (flags.single("emit")) |emit_flag| {
461 if (mem.eql(u8, emit_flag, "asm")) {
462 emit_type = Module.Emit.Assembly;
463 } else if (mem.eql(u8, emit_flag, "bin")) {
464 emit_type = Module.Emit.Binary;
465 } else if (mem.eql(u8, emit_flag, "llvm-ir")) {
466 emit_type = Module.Emit.LlvmIr;
295 const emit_type = blk: {
296 if (flags.single("emit")) |emit_flag| {
297 if (mem.eql(u8, emit_flag, "asm")) {
298 break :blk Module.Emit.Assembly;
299 } else if (mem.eql(u8, emit_flag, "bin")) {
300 break :blk Module.Emit.Binary;
301 } else if (mem.eql(u8, emit_flag, "llvm-ir")) {
302 break :blk Module.Emit.LlvmIr;
303 } else unreachable;
467304 } else {
468 unreachable;
305 break :blk Module.Emit.Binary;
469306 }
470 }
307 };
471308
472 var cur_pkg = try Module.CliPkg.init(allocator, "", "", null); // TODO: Need a path, name?
309 var cur_pkg = try CliPkg.init(allocator, "", "", null);
473310 defer cur_pkg.deinit();
474311
475312 var i: usize = 0;
......@@ -482,15 +319,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
482319 i += 1;
483320 const new_pkg_path = args[i];
484321
485 var new_cur_pkg = try Module.CliPkg.init(allocator, new_pkg_name, new_pkg_path, cur_pkg);
322 var new_cur_pkg = try CliPkg.init(allocator, new_pkg_name, new_pkg_path, cur_pkg);
486323 try cur_pkg.children.append(new_cur_pkg);
487324 cur_pkg = new_cur_pkg;
488325 } else if (mem.eql(u8, "--pkg-end", arg_name)) {
489 if (cur_pkg.parent == null) {
326 if (cur_pkg.parent) |parent| {
327 cur_pkg = parent;
328 } else {
490329 try stderr.print("encountered --pkg-end with no matching --pkg-begin\n");
491330 os.exit(1);
492331 }
493 cur_pkg = cur_pkg.parent.?;
494332 }
495333 }
496334
......@@ -499,43 +337,42 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
499337 os.exit(1);
500338 }
501339
502 var in_file: ?[]const u8 = undefined;
503 switch (flags.positionals.len) {
504 0 => {
505 try stderr.write("--name [name] not provided and unable to infer\n");
506 os.exit(1);
507 },
508 1 => {
509 in_file = flags.positionals.at(0);
510 },
340 const provided_name = flags.single("name");
341 const root_source_file = switch (flags.positionals.len) {
342 0 => null,
343 1 => flags.positionals.at(0),
511344 else => {
512 try stderr.write("only one zig input file is accepted during build\n");
345 try stderr.print("unexpected extra parameter: {}\n", flags.positionals.at(1));
513346 os.exit(1);
514347 },
515 }
348 };
516349
517 const basename = os.path.basename(in_file.?);
518 var it = mem.split(basename, ".");
519 const root_name = it.next() orelse {
520 try stderr.write("file name cannot be empty\n");
521 os.exit(1);
350 const root_name = if (provided_name) |n| n else blk: {
351 if (root_source_file) |file| {
352 const basename = os.path.basename(file);
353 var it = mem.split(basename, ".");
354 break :blk it.next() orelse basename;
355 } else {
356 try stderr.write("--name [name] not provided and unable to infer\n");
357 os.exit(1);
358 }
522359 };
523360
524 const asm_a = flags.many("assembly");
525 const obj_a = flags.many("object");
526 if (in_file == null and (obj_a == null or obj_a.?.len == 0) and (asm_a == null or asm_a.?.len == 0)) {
361 const assembly_files = flags.many("assembly");
362 const link_objects = flags.many("object");
363 if (root_source_file == null and link_objects.len == 0 and assembly_files.len == 0) {
527364 try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");
528365 os.exit(1);
529366 }
530367
531 if (out_type == Module.Kind.Obj and (obj_a != null and obj_a.?.len != 0)) {
368 if (out_type == Module.Kind.Obj and link_objects.len != 0) {
532369 try stderr.write("When building an object file, --object arguments are invalid\n");
533370 os.exit(1);
534371 }
535372
536 const zig_root_source_file = in_file;
537
538 const full_cache_dir = os.path.resolve(allocator, ".", flags.single("cache-dir") orelse "zig-cache"[0..]) catch {
373 const rel_cache_dir = flags.single("cache-dir") orelse "zig-cache"[0..];
374 const full_cache_dir = os.path.resolve(allocator, ".", rel_cache_dir) catch {
375 try stderr.print("invalid cache dir: {}\n", rel_cache_dir);
539376 os.exit(1);
540377 };
541378 defer allocator.free(full_cache_dir);
......@@ -546,7 +383,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
546383 var module = try Module.create(
547384 allocator,
548385 root_name,
549 zig_root_source_file,
386 root_source_file,
550387 Target.Native,
551388 out_type,
552389 build_mode,
......@@ -561,24 +398,21 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
561398
562399 module.is_test = false;
563400
564 if (flags.single("linker-script")) |linker_script| {
565 module.linker_script = linker_script;
566 }
567
401 module.linker_script = flags.single("linker-script");
568402 module.each_lib_rpath = flags.present("each-lib-rpath");
569403
570404 var clang_argv_buf = ArrayList([]const u8).init(allocator);
571405 defer clang_argv_buf.deinit();
572 if (flags.many("mllvm")) |mllvm_flags| {
573 for (mllvm_flags) |mllvm| {
574 try clang_argv_buf.append("-mllvm");
575 try clang_argv_buf.append(mllvm);
576 }
577406
578 module.llvm_argv = mllvm_flags;
579 module.clang_argv = clang_argv_buf.toSliceConst();
407 const mllvm_flags = flags.many("mllvm");
408 for (mllvm_flags) |mllvm| {
409 try clang_argv_buf.append("-mllvm");
410 try clang_argv_buf.append(mllvm);
580411 }
581412
413 module.llvm_argv = mllvm_flags;
414 module.clang_argv = clang_argv_buf.toSliceConst();
415
582416 module.strip = flags.present("strip");
583417 module.is_static = flags.present("static");
584418
......@@ -610,18 +444,9 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
610444 module.verbose_cimport = flags.present("verbose-cimport");
611445
612446 module.err_color = color;
613
614 if (flags.many("library-path")) |lib_dirs| {
615 module.lib_dirs = lib_dirs;
616 }
617
618 if (flags.many("framework")) |frameworks| {
619 module.darwin_frameworks = frameworks;
620 }
621
622 if (flags.many("rpath")) |rpath_list| {
623 module.rpath_list = rpath_list;
624 }
447 module.lib_dirs = flags.many("library-path");
448 module.darwin_frameworks = flags.many("framework");
449 module.rpath_list = flags.many("rpath");
625450
626451 if (flags.single("output-h")) |output_h| {
627452 module.out_h_path = output_h;
......@@ -644,41 +469,25 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
644469 }
645470
646471 module.emit_file_type = emit_type;
647 if (flags.many("object")) |objects| {
648 module.link_objects = objects;
649 }
650 if (flags.many("assembly")) |assembly_files| {
651 module.assembly_files = assembly_files;
652 }
472 module.link_objects = link_objects;
473 module.assembly_files = assembly_files;
653474
654475 try module.build();
655 try module.link(flags.single("out-file") orelse null);
656
657 if (flags.present("print-timing-info")) {
658 // codegen_print_timing_info(g, stderr);
659 }
660
661 try stderr.print("building {}: {}\n", @tagName(out_type), in_file);
476 try module.link(flags.single("out-file"));
662477}
663478
664479fn cmdBuildExe(allocator: *Allocator, args: []const []const u8) !void {
665 try buildOutputType(allocator, args, Module.Kind.Exe);
480 return buildOutputType(allocator, args, Module.Kind.Exe);
666481}
667482
668// cmd:build-lib ///////////////////////////////////////////////////////////////////////////////////
669
670483fn cmdBuildLib(allocator: *Allocator, args: []const []const u8) !void {
671 try buildOutputType(allocator, args, Module.Kind.Lib);
484 return buildOutputType(allocator, args, Module.Kind.Lib);
672485}
673486
674// cmd:build-obj ///////////////////////////////////////////////////////////////////////////////////
675
676487fn cmdBuildObj(allocator: *Allocator, args: []const []const u8) !void {
677 try buildOutputType(allocator, args, Module.Kind.Obj);
488 return buildOutputType(allocator, args, Module.Kind.Obj);
678489}
679490
680// cmd:fmt /////////////////////////////////////////////////////////////////////////////////////////
681
682491const usage_fmt =
683492 \\usage: zig fmt [file]...
684493 \\
......@@ -735,7 +544,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
735544 defer flags.deinit();
736545
737546 if (flags.present("help")) {
738 try stderr.write(usage_fmt);
547 try stdout.write(usage_fmt);
739548 os.exit(0);
740549 }
741550
......@@ -863,162 +672,16 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
863672 }
864673}
865674
866// cmd:version /////////////////////////////////////////////////////////////////////////////////////
867
868675fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {
869676 try stdout.print("{}\n", std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
870677}
871678
872// cmd:test ////////////////////////////////////////////////////////////////////////////////////////
873
874const usage_test =
875 \\usage: zig test [file]...
876 \\
877 \\Options:
878 \\ --help Print this help and exit
879 \\
880 \\
881;
882
883679const args_test_spec = []Flag{Flag.Bool("--help")};
884680
885fn cmdTest(allocator: *Allocator, args: []const []const u8) !void {
886 var flags = try Args.parse(allocator, args_build_spec, args);
887 defer flags.deinit();
888
889 if (flags.present("help")) {
890 try stderr.write(usage_test);
891 os.exit(0);
892 }
893
894 if (flags.positionals.len != 1) {
895 try stderr.write("expected exactly one zig source file\n");
896 os.exit(1);
897 }
898
899 // compile the test program into the cache and run
900
901 // NOTE: May be overlap with buildOutput, take the shared part out.
902 try stderr.print("testing file {}\n", flags.positionals.at(0));
903}
904
905// cmd:run /////////////////////////////////////////////////////////////////////////////////////////
906
907// Run should be simple and not expose the full set of arguments provided by build-exe. If specific
908// build requirements are need, the user should `build-exe` then `run` manually.
909const usage_run =
910 \\usage: zig run [file] -- <runtime args>
911 \\
912 \\Options:
913 \\ --help Print this help and exit
914 \\
915 \\
916;
917
918const args_run_spec = []Flag{Flag.Bool("--help")};
919
920fn cmdRun(allocator: *Allocator, args: []const []const u8) !void {
921 var compile_args = args;
922 var runtime_args: []const []const u8 = []const []const u8{};
923
924 for (args) |argv, i| {
925 if (mem.eql(u8, argv, "--")) {
926 compile_args = args[0..i];
927 runtime_args = args[i + 1 ..];
928 break;
929 }
930 }
931 var flags = try Args.parse(allocator, args_run_spec, compile_args);
932 defer flags.deinit();
933
934 if (flags.present("help")) {
935 try stderr.write(usage_run);
936 os.exit(0);
937 }
938
939 if (flags.positionals.len != 1) {
940 try stderr.write("expected exactly one zig source file\n");
941 os.exit(1);
942 }
943
944 try stderr.print("runtime args:\n");
945 for (runtime_args) |cargs| {
946 try stderr.print("{}\n", cargs);
947 }
948}
949
950// cmd:translate-c /////////////////////////////////////////////////////////////////////////////////
951
952const usage_translate_c =
953 \\usage: zig translate-c [file]
954 \\
955 \\Options:
956 \\ --help Print this help and exit
957 \\ --enable-timing-info Print timing diagnostics
958 \\ --output [path] Output file to write generated zig file (default: stdout)
959 \\
960 \\
961;
962
963const args_translate_c_spec = []Flag{
964 Flag.Bool("--help"),
965 Flag.Bool("--enable-timing-info"),
966 Flag.Arg1("--libc-include-dir"),
967 Flag.Arg1("--output"),
968};
969
970fn cmdTranslateC(allocator: *Allocator, args: []const []const u8) !void {
971 var flags = try Args.parse(allocator, args_translate_c_spec, args);
972 defer flags.deinit();
973
974 if (flags.present("help")) {
975 try stderr.write(usage_translate_c);
976 os.exit(0);
977 }
978
979 if (flags.positionals.len != 1) {
980 try stderr.write("expected exactly one c source file\n");
981 os.exit(1);
982 }
983
984 // set up codegen
985
986 const zig_root_source_file = null;
987
988 // NOTE: translate-c shouldn't require setting up the full codegen instance as it does in
989 // the C++ compiler.
990
991 // codegen_create(g);
992 // codegen_set_out_name(g, null);
993 // codegen_translate_c(g, flags.positional.at(0))
994
995 var output_stream = stdout;
996 if (flags.single("output")) |output_file| {
997 var file = try os.File.openWrite(allocator, output_file);
998 defer file.close();
999
1000 var file_stream = io.FileOutStream.init(&file);
1001 // TODO: Not being set correctly, still stdout
1002 output_stream = &file_stream.stream;
1003 }
1004
1005 // ast_render(g, output_stream, g->root_import->root, 4);
1006 try output_stream.write("pub const example = 10;\n");
1007
1008 if (flags.present("enable-timing-info")) {
1009 // codegen_print_timing_info(g, stdout);
1010 try stderr.write("printing timing info for translate-c\n");
1011 }
1012}
1013
1014// cmd:help ////////////////////////////////////////////////////////////////////////////////////////
1015
1016681fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {
1017 try stderr.write(usage);
682 try stdout.write(usage);
1018683}
1019684
1020// cmd:zen /////////////////////////////////////////////////////////////////////////////////////////
1021
1022685const info_zen =
1023686 \\
1024687 \\ * Communicate intent precisely.
......@@ -1040,8 +703,6 @@ fn cmdZen(allocator: *Allocator, args: []const []const u8) !void {
1040703 try stdout.write(info_zen);
1041704}
1042705
1043// cmd:internal ////////////////////////////////////////////////////////////////////////////////////
1044
1045706const usage_internal =
1046707 \\usage: zig internal [subcommand]
1047708 \\
......@@ -1095,3 +756,28 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {
1095756 std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
1096757 );
1097758}
759
760const CliPkg = struct {
761 name: []const u8,
762 path: []const u8,
763 children: ArrayList(*CliPkg),
764 parent: ?*CliPkg,
765
766 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
767 var pkg = try allocator.create(CliPkg{
768 .name = name,
769 .path = path,
770 .children = ArrayList(*CliPkg).init(allocator),
771 .parent = parent,
772 });
773 return pkg;
774 }
775
776 pub fn deinit(self: *CliPkg) void {
777 for (self.children.toSliceConst()) |child| {
778 child.deinit();
779 }
780 self.children.deinit();
781 }
782};
783
src-self-hosted/module.zig-24
......@@ -103,30 +103,6 @@ pub const Module = struct {
103103 LlvmIr,
104104 };
105105
106 pub const CliPkg = struct {
107 name: []const u8,
108 path: []const u8,
109 children: ArrayList(*CliPkg),
110 parent: ?*CliPkg,
111
112 pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
113 var pkg = try allocator.create(CliPkg{
114 .name = name,
115 .path = path,
116 .children = ArrayList(*CliPkg).init(allocator),
117 .parent = parent,
118 });
119 return pkg;
120 }
121
122 pub fn deinit(self: *CliPkg) void {
123 for (self.children.toSliceConst()) |child| {
124 child.deinit();
125 }
126 self.children.deinit();
127 }
128 };
129
130106 pub fn create(
131107 allocator: *mem.Allocator,
132108 name: []const u8,
test/cases/bugs/1111.zig+3-3
......@@ -5,8 +5,8 @@ const Foo = extern enum {
55test "issue 1111 fixed" {
66 const v = Foo.Bar;
77
8 switch(v) {
9 Foo.Bar => return,
10 else => return,
8 switch (v) {
9 Foo.Bar => return,
10 else => return,
1111 }
1212}