diff options
55 files changed, 270 insertions, 35 deletions
@@ -1,3 +1,5 @@ *~ *.swp zig-cache/ +answers/ +patches/healed/ @@ -32,54 +32,61 @@ Verify the installation and version of `zig` like so: ```bash $ zig version -0.8.0-dev.1065+<some hexadecimal string> +0.8.0-dev.1065+xxxxxxxxx ``` Clone this repository with Git: ```bash -git clone https://github.com/ratfactor/ziglings -cd ziglings +$ git clone https://github.com/ratfactor/ziglings +$ cd ziglings ``` Then run `zig build` and follow the instructions to begin! ```bash -zig build +$ zig build ``` -## A Note About Compiler Versions +## A Note About Versions The Zig language is under very active development. Ziglings will attempt to be current, but not bleeding-edge. However, sometimes fundamental changes -will happen. Ziglings will check for a minimum version and build number -(which is this one: `0.x.x-dev.<build number>`) and exit if your version of -Zig is too old. It is likely that you'll download a build which is greater -than the number in the example shown above in this README. That's okay! +will happen. Ziglings will check for a minimum version and build number. + +(See Getting Started above for the current minimum.) + +It is likely that you'll download a build which is _greater_ than the minimum. Once you have a version of the Zig compiler that works with your copy of -Ziglings, they'll continue to work together forever. But if you update one, -keep in mind that you may need to also update the other. +Ziglings, they'll continue to work together. But if you update one, you may +need to also update the other. -## Manual Usage +## Advanced Usage -If you want to run a single file for testing, you can do so with this command: +It can be handy to check just a single exercise or _start_ from a single +exercise: ```bash -zig run exercises/01_hello.zig +zig build 19 +zig build 19_start ``` -or, alternatively + +You can also run without checking for correctness: + ```bash zig build 01_test ``` -To verify a single file, use +Or skip the build system entirely and interact directly with the compiler +if you're into that sort of thing: ```bash -zig build 01_only +zig run exercises/01_hello.zig ``` -To prepare an executable for debugging, install it to zig-cache/bin with +Calling all wizards: To prepare an executable for debugging, install it +to zig-cache/bin with: ```bash zig build 01_install @@ -112,13 +119,13 @@ Planned exercises: * [x] Enums * [x] Structs * [x] Pointers -* [ ] Multi pointers +* [ ] Optionals * [ ] Slices +* [ ] Multi pointers * [ ] Unions * [ ] Numeric types (integers, floats) * [ ] Labelled blocks and loops * [ ] Loops as expressions -* [ ] Optionals * [ ] Comptime * [ ] Inline loops (how to DEMO this?) * [ ] Anonymous structs @@ -236,6 +236,14 @@ const exercises = [_]Exercise{ .output = "Elephant A. Elephant B. Elephant C.", .hint = "Oh no! We forgot Elephant B!", }, + .{ + .main_file = "45_optionals.zig", + .output = "The Ultimate Answer: 42.", + }, + // optional fields (elephant tail - no longer need circular) + // super-simple struct method + // use struct method for elephant tails + // quiz: add elephant trunk (like tail)! }; /// Check the zig version to make sure it can compile the examples properly. @@ -263,7 +271,11 @@ pub fn build(b: *Builder) void { // very old versions of Zig used warn instead of print. const stderrPrintFn = if (@hasDecl(std.debug, "print")) std.debug.print else std.debug.warn; stderrPrintFn( - \\Error: Your version of zig is too old. Please download a master build from + \\ERROR: Sorry, it looks like your version of zig is too old. :-( + \\ + \\The README lists the minimum version and build number. + \\ + \\Please download a master build from \\https://ziglang.org/download/ \\ , .{}); @@ -316,39 +328,41 @@ pub fn build(b: *Builder) void { \\ , .{}); - const verify_all = b.step("ziglings", "Verify all ziglings"); + const verify_all = b.step("ziglings", "Check all ziglings"); verify_all.dependOn(&header_step.step); b.default_step = verify_all; var prev_chain_verify = verify_all; + const use_healed = b.option(bool, "healed", "Run exercises from patches/healed") orelse false; + for (exercises) |ex| { const base_name = ex.baseName(); const file_path = std.fs.path.join(b.allocator, &[_][]const u8{ - "exercises", ex.main_file, + if (use_healed) "patches/healed" else "exercises", ex.main_file, }) catch unreachable; const build_step = b.addExecutable(base_name, file_path); build_step.install(); - const verify_step = ZiglingStep.create(b, ex); + const verify_step = ZiglingStep.create(b, ex, use_healed); const key = ex.key(); - const named_test = b.step(b.fmt("{s}_test", .{key}), b.fmt("Run {s} without verifying output", .{ex.main_file})); + const named_test = b.step(b.fmt("{s}_test", .{key}), b.fmt("Run {s} without checking output", .{ex.main_file})); const run_step = build_step.run(); named_test.dependOn(&run_step.step); const named_install = b.step(b.fmt("{s}_install", .{key}), b.fmt("Install {s} to zig-cache/bin", .{ex.main_file})); named_install.dependOn(&build_step.install_step.?.step); - const named_verify = b.step(b.fmt("{s}_only", .{key}), b.fmt("Verify {s} only", .{ex.main_file})); + const named_verify = b.step(key, b.fmt("Check {s} only", .{ex.main_file})); named_verify.dependOn(&verify_step.step); const chain_verify = b.allocator.create(Step) catch unreachable; chain_verify.* = Step.initNoOp(.Custom, b.fmt("chain {s}", .{key}), b.allocator); chain_verify.dependOn(&verify_step.step); - const named_chain = b.step(key, b.fmt("Verify all solutions starting at {s}", .{ex.main_file})); + const named_chain = b.step(b.fmt("{s}_start", .{key}), b.fmt("Check all solutions starting at {s}", .{ex.main_file})); named_chain.dependOn(&header_step.step); named_chain.dependOn(chain_verify); @@ -367,13 +381,15 @@ const ZiglingStep = struct { step: Step, exercise: Exercise, builder: *Builder, + use_healed: bool, - pub fn create(builder: *Builder, exercise: Exercise) *@This() { + pub fn create(builder: *Builder, exercise: Exercise, use_healed: bool) *@This() { const self = builder.allocator.create(@This()) catch unreachable; self.* = .{ .step = Step.init(.Custom, exercise.main_file, builder.allocator, make), .exercise = exercise, .builder = builder, + .use_healed = use_healed, }; return self; } @@ -382,7 +398,7 @@ const ZiglingStep = struct { const self = @fieldParentPtr(@This(), "step", step); self.makeInternal() catch { if (self.exercise.hint.len > 0) { - print("\n{s}hint: {s}{s}", .{ bold_text, self.exercise.hint, reset_text }); + print("\n{s}HINT: {s}{s}", .{ bold_text, self.exercise.hint, reset_text }); } print("\n{s}Edit exercises/{s} and run this again.{s}", .{ red_text, self.exercise.main_file, reset_text }); @@ -396,7 +412,7 @@ const ZiglingStep = struct { const exe_file = try self.doCompile(); - print("Verifying {s}...\n", .{self.exercise.main_file}); + print("Checking {s}...\n", .{self.exercise.main_file}); const cwd = self.builder.build_root; @@ -463,7 +479,7 @@ const ZiglingStep = struct { return error.InvalidOutput; } - print("{s}** PASSED **{s}\n", .{ green_text, reset_text }); + print("{s}PASSED: {s}{s}\n", .{ green_text, output, reset_text }); } // The normal compile step calls os.exit, so we can't use it as a library :( @@ -482,7 +498,8 @@ const ZiglingStep = struct { zig_args.append(@tagName(builder.color)) catch unreachable; } - const zig_file = std.fs.path.join(builder.allocator, &[_][]const u8{ "exercises", self.exercise.main_file }) catch unreachable; + const zig_file = std.fs.path.join(builder.allocator, &[_][]const u8{ + if (self.use_healed) "patches/healed" else "exercises", self.exercise.main_file }) catch unreachable; zig_args.append(builder.pathFromRoot(zig_file)) catch unreachable; zig_args.append("--cache-dir") catch unreachable; diff --git a/exercises/03_assignment.zig b/exercises/03_assignment.zig index 662fd18..3775afc 100644 --- a/exercises/03_assignment.zig +++ b/exercises/03_assignment.zig @@ -15,7 +15,7 @@ // bar CAN be negative and can hold −128 to 127 // // const foo: u8 = 20; -// var bar: i8 = -20; +// const bar: i8 = -20; // // Example: foo can hold 8 bits (0 to 255) // bar can hold 16 bits (0 to 65,535) diff --git a/exercises/19_functions2.zig b/exercises/19_functions2.zig index 4d195a7..99319c3 100644 --- a/exercises/19_functions2.zig +++ b/exercises/19_functions2.zig @@ -1,7 +1,7 @@ // // Now let's create a function that takes a parameter. Here's an // example that takes two parameters. As you can see, parameters -// are declared just like an other types ("name": "type"): +// are declared just like any other types ("name": "type"): // // fn myFunction( number: u8, is_lucky: bool ) { // ... diff --git a/exercises/22_errors2.zig b/exercises/22_errors2.zig index 0f8571f..7675d2d 100644 --- a/exercises/22_errors2.zig +++ b/exercises/22_errors2.zig @@ -10,7 +10,7 @@ // Zig lets us make what's called an "error union" which is a value // which could either be a regular value OR an error from a set: // -// var text: MyErrorSet!Text = getText('foo.txt'); +// var text: MyErrorSet!Text = getText('foo.txt'); // // For now, let's just see if we can try making an error union! // diff --git a/exercises/45_optionals.zig b/exercises/45_optionals.zig new file mode 100644 index 0000000..815ba75 --- /dev/null +++ b/exercises/45_optionals.zig @@ -0,0 +1,52 @@ +// +// Sometimes you know that a variable might hold a value or +// it might not. Zig has a neat way of expressing this idea +// called Optionals. An optional type just has a '?' like this: +// +// var foo: ?u32 = 10; +// +// Now foo can store a u32 integer OR null (a value storing +// the cosmic horror of a value NOT EXISTING!) +// +// foo = null; +// +// if (foo == null) beginScreaming(); +// +// Before we can use the optional value as the non-null type +// (a u32 integer in this case), we need to guarantee that it +// isn't null. One way to do this is to THREATEN IT with the +// "orelse" statement. +// +// var bar = foo orelse 2; +// +// Here, bar will either equal the u32 integer value stored in +// foo, or it will equal 2 if foo was null. +// +const std = @import("std"); + +pub fn main() void { + const result = deepThought(); + + // Please threaten the result so that answer is either the + // integer value from deepThought() OR the number 42: + var answer: u8 = result; + + std.debug.print("The Ultimate Answer: {}.\n",.{answer}); +} + +fn deepThought() ?u8 { + // It seems Deep Thought's output has declined in quality. + // But we'll leave this as-is. Sorry Deep Thought. + return null; +} +// +// Blast from the past: +// +// Optionals are a lot like error union types which can either +// hold a value or an error. Likewise, the orelse statement is +// like the catch statement used to "unwrap" a value or supply +// a default value: +// +// var maybe_bad: Error!u32 = Error.Evil; +// var number: u32 = maybe_bad catch 0; +// diff --git a/patches/README.md b/patches/README.md new file mode 100644 index 0000000..b3249fa --- /dev/null +++ b/patches/README.md @@ -0,0 +1,35 @@ +# No Peeking! :-) + +Welcome to the ziglings/patches directory. This is how ziglings is tested. + +The patches fix the broken exercises so that they work again, which means the +answers are here, so no peeking! + +## Éowyn + +A Bash shell script named `eowyn.sh` dwells here. She heals the little broken +programs and places them in a `healed` directory, which is NOT committed to the +repo. + +```bash +$ ./eowyn.sh +``` + +(If you invoke her from elsewhere, she'll come here to ply her trade.) + +The `build.zig` build script at the heart of Ziglings has a top-secret option +which tells it to test from the `patches/healed/` dir rather than `exercises/`: + +```bash +$ zig build -Dhealed [step] +``` + +Éowyn tests all healed programs using this secret option. + + +## Gollum + +Another Bash shell script named `gollum.sh` may also be found. He snatches the +original answers and stows them in his secret answers stash. If you leave him +alone, he'll leave you alone. + diff --git a/patches/eowyn.sh b/patches/eowyn.sh new file mode 100755 index 0000000..5a802f6 --- /dev/null +++ b/patches/eowyn.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# "I will be a shieldmaiden no longer, +# nor vie with the great Riders, nor +# take joy only in the songs of slaying. +# I will be a healer, and love all things +# that grow and are not barren." +# Éowyn, The Return of the King +# +# +# This script shall heal the little broken programs +# using the patches in this directory and convey them +# to convalesce in the healed directory. +# + +# We run from the patches dir. Go there now if not already. +cd $(dirname $(which $0)) +pwd # Show it upon the screen so all shall be made apparent. + +# Create healed/ directory here if it doesn't already exist. +mkdir -p healed + +# Cycle through all the little broken Zig applications. +for broken in ../exercises/*.zig +do + # Remove the dir and extension, rendering the True Name. + true_name=$(basename $broken .zig) + patch_name="patches/$true_name.patch" + + + if [[ -f $patch_name ]] + then + # Apply the bandages to the wounds, grow new limbs, let + # new life spring into the broken bodies of the fallen. + echo Healing $true_name... + patch --output=healed/$true_name.zig $broken $patch_name + else + echo Cannot heal $true_name. Making empty patch. + echo > $patch_name + fi +done + +# Return to the home of our ancestors. +cd .. + +# Test the healed exercises. May the compiler have mercy upon us. +zig build -Dhealed diff --git a/patches/gollum.sh b/patches/gollum.sh new file mode 100755 index 0000000..423d376 --- /dev/null +++ b/patches/gollum.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# "It isn't fair, my precious, is it, +# to ask us what it's got in it's +# nassty little pocketsess?" +# Gollum, The Hobbit, or There and Back Again +# + +cd $(dirname $(which $0)) +f=$(basename ../exercises/$1*.zig .zig 2> /dev/null) +b=../exercises/$f.zig +a=../answers/$f.zig +p=patches/$f.patch + +printf "\tf: '$f'\n\tb: '$b'\n\ta: '$a'\n" + +if [[ ! -f $b ]]; then echo "We hates it!"; exit 1; fi +if [[ ! -a $a ]]; then echo "Where is it? Where is the answer, precious?"; exit; fi + +echo Hisssss! + +diff $b $a > $p + +cat $p diff --git a/patches/patches/01_hello.patch b/patches/patches/01_hello.patch new file mode 100644 index 0000000..fb360a7 --- /dev/null +++ b/patches/patches/01_hello.patch @@ -0,0 +1,4 @@ +19c19 +< fn main() void { +--- +> pub fn main() void { diff --git a/patches/patches/02_std.patch b/patches/patches/02_std.patch new file mode 100644 index 0000000..6c97adb --- /dev/null +++ b/patches/patches/02_std.patch @@ -0,0 +1,4 @@ +14c14 +< ??? = @import("std"); +--- +> const std = @import("std"); diff --git a/patches/patches/03_assignment.patch b/patches/patches/03_assignment.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/03_assignment.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/04_arrays.patch b/patches/patches/04_arrays.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/04_arrays.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/05_arrays2.patch b/patches/patches/05_arrays2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/05_arrays2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/06_strings.patch b/patches/patches/06_strings.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/06_strings.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/07_strings2.patch b/patches/patches/07_strings2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/07_strings2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/08_quiz.patch b/patches/patches/08_quiz.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/08_quiz.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/09_if.patch b/patches/patches/09_if.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/09_if.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/10_if2.patch b/patches/patches/10_if2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/10_if2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/11_while.patch b/patches/patches/11_while.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/11_while.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/12_while2.patch b/patches/patches/12_while2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/12_while2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/13_while3.patch b/patches/patches/13_while3.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/13_while3.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/14_while4.patch b/patches/patches/14_while4.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/14_while4.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/15_for.patch b/patches/patches/15_for.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/15_for.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/16_for2.patch b/patches/patches/16_for2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/16_for2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/17_quiz2.patch b/patches/patches/17_quiz2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/17_quiz2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/18_functions.patch b/patches/patches/18_functions.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/18_functions.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/19_functions2.patch b/patches/patches/19_functions2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/19_functions2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/20_quiz3.patch b/patches/patches/20_quiz3.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/20_quiz3.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/21_errors.patch b/patches/patches/21_errors.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/21_errors.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/22_errors2.patch b/patches/patches/22_errors2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/22_errors2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/23_errors3.patch b/patches/patches/23_errors3.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/23_errors3.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/24_errors4.patch b/patches/patches/24_errors4.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/24_errors4.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/25_errors5.patch b/patches/patches/25_errors5.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/25_errors5.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/26_hello2.patch b/patches/patches/26_hello2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/26_hello2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/27_defer.patch b/patches/patches/27_defer.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/27_defer.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/28_defer2.patch b/patches/patches/28_defer2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/28_defer2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/29_errdefer.patch b/patches/patches/29_errdefer.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/29_errdefer.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/30_switch.patch b/patches/patches/30_switch.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/30_switch.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/31_switch2.patch b/patches/patches/31_switch2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/31_switch2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/32_unreachable.patch b/patches/patches/32_unreachable.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/32_unreachable.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/33_iferror.patch b/patches/patches/33_iferror.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/33_iferror.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/34_quiz4.patch b/patches/patches/34_quiz4.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/34_quiz4.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/35_enums.patch b/patches/patches/35_enums.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/35_enums.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/36_enums2.patch b/patches/patches/36_enums2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/36_enums2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/37_structs.patch b/patches/patches/37_structs.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/37_structs.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/38_structs2.patch b/patches/patches/38_structs2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/38_structs2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/39_pointers.patch b/patches/patches/39_pointers.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/39_pointers.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/40_pointers2.patch b/patches/patches/40_pointers2.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/40_pointers2.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/41_pointers3.patch b/patches/patches/41_pointers3.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/41_pointers3.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/42_pointers4.patch b/patches/patches/42_pointers4.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/42_pointers4.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/43_pointers5.patch b/patches/patches/43_pointers5.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/43_pointers5.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/44_quiz5.patch b/patches/patches/44_quiz5.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/44_quiz5.patch @@ -0,0 +1 @@ + diff --git a/patches/patches/45_optionals.patch b/patches/patches/45_optionals.patch new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/patches/45_optionals.patch @@ -0,0 +1 @@ + |