From 55bc1c39a6c97772cca0b477274dfc71ca261f6c Mon Sep 17 00:00:00 2001 From: Michael Chalupiak Date: Sat, 19 Jul 2025 23:05:38 -0400 Subject: [PATCH] Initial Commit --- .gitignore | 63 ++++++++++++++++++++++ README.md | 5 ++ c/Makefile | 5 ++ c/ssg.c | 77 ++++++++++++++++++++++++++ c3/docs/.gitkeep | 0 c3/lib/.gitkeep | 0 c3/project.json | 43 +++++++++++++++ c3/resources/.gitkeep | 0 c3/scripts/.gitkeep | 0 c3/src/.gitkeep | 0 c3/src/main.c3 | 8 +++ c3/test/.gitkeep | 0 cpp/CMakeLists.txt | 34 ++++++++++++ cpp/ssg.cpp | 13 +++++ go/go.mod | 3 ++ go/ssg.go | 7 +++ hare/Makefile | 5 ++ hare/ssg.ha | 5 ++ markdown_files/intro.md | 17 ++++++ nim/src/ssg.nim | 5 ++ nim/ssg.nimble | 13 +++++ odin/ssg.odin | 7 +++ rust/Cargo.lock | 7 +++ rust/Cargo.toml | 6 +++ rust/src/main.rs | 3 ++ swift/Package.resolved | 15 ++++++ swift/Package.swift | 21 ++++++++ swift/Sources/ssg.swift | 14 +++++ zig/build.zig | 116 ++++++++++++++++++++++++++++++++++++++++ zig/build.zig.zon | 86 +++++++++++++++++++++++++++++ zig/src/main.zig | 39 ++++++++++++++ 31 files changed, 617 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 c/Makefile create mode 100644 c/ssg.c create mode 100644 c3/docs/.gitkeep create mode 100644 c3/lib/.gitkeep create mode 100644 c3/project.json create mode 100644 c3/resources/.gitkeep create mode 100644 c3/scripts/.gitkeep create mode 100644 c3/src/.gitkeep create mode 100644 c3/src/main.c3 create mode 100644 c3/test/.gitkeep create mode 100644 cpp/CMakeLists.txt create mode 100644 cpp/ssg.cpp create mode 100644 go/go.mod create mode 100644 go/ssg.go create mode 100644 hare/Makefile create mode 100644 hare/ssg.ha create mode 100644 markdown_files/intro.md create mode 100644 nim/src/ssg.nim create mode 100644 nim/ssg.nimble create mode 100644 odin/ssg.odin create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/src/main.rs create mode 100644 swift/Package.resolved create mode 100644 swift/Package.swift create mode 100644 swift/Sources/ssg.swift create mode 100644 zig/build.zig create mode 100644 zig/build.zig.zon create mode 100644 zig/src/main.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e26b9fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +## C +c/*.o +c/ssg + +## C3 +c3/build + +## C++ +cpp/CMakeLists.txt.user +cpp/CMakeCache.txt +cpp/CMakeFiles +cpp/CMakeScripts +cpp/Testing +cpp/Makefile +cpp/cmake_install.cmake +cpp/install_manifest.txt +cpp/compile_commands.json +cpp/CTestTestfile.cmake +cpp/_deps +cpp/CMakeUserPresets.json +cpp/*.o +cpp/ssg + +## Go +go/*.o +go/ssg + +## Hare +hare/*.o +hare/ssg + +## Jai +jai/*.o +jai/ssg + +## Nim +nim/nimcache +nim/nimblecache +nim/htmldocs + +## Odin +odin/*.o +odin/ssg +odin/odin + +## Rust +rust/debug +rust/target + +## Swift +swift/.DS_Store +swift/.build +swift/Packages +swift/xcuserdata/ +swift/DerivedData/ +swift/.swiftpm/configuration/registries.json +swift/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +swift/.netrc + +## Zig +zig/.zig-cache +zig/zig-out +zig/*.o diff --git a/README.md b/README.md new file mode 100644 index 0000000..c596228 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Static Site Generator + +This is the static site generator I plan to use for my [website](mchalupiak.com), once it is complete. +I also plan to implement it in multiple languages just to get a feel for them, as it should be fairly simple. +The only dependency will be on the [md4c](https://github.com/mity/md4c) markdown parsing library (for now) diff --git a/c/Makefile b/c/Makefile new file mode 100644 index 0000000..304e6e6 --- /dev/null +++ b/c/Makefile @@ -0,0 +1,5 @@ +all: + cc ssg.c -lmd4c -lmd4c-html -O2 -Wall -o ssg + +run: all + ./ssg diff --git a/c/ssg.c b/c/ssg.c new file mode 100644 index 0000000..48ebb7e --- /dev/null +++ b/c/ssg.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include + +#define MD4C_USE_UTF8 + +char* combine_strs(char* str1, char* str2) { + int str1_len = strlen(str1); + int str2_len = strlen(str2); + char* output_buffer = malloc((str1_len + str2_len + 1) * sizeof(char)); + if (output_buffer == NULL) { + printf("Error: Allocation Error\n"); + return NULL; + } + memset(output_buffer, '\0', str1_len + str2_len + 1); + strncat(output_buffer, str1, str1_len); + strncat(output_buffer, str2, str2_len); + return output_buffer; +} + +void* process(const MD_CHAR* text, MD_SIZE text_size, void* output) { + char* output_filename = combine_strs("output/", output); + if (output_filename == NULL) { + printf("Error: Unable to create filename buffer... Exiting\n"); + exit(3); + } + FILE* output_file = fopen(output_filename, ""); + if (output_file == NULL) { + printf("Error: Cannot open output file %s... Exiting\n", output_filename); + free(output_filename); + exit(4); + } + free(output_filename); + int bytes = fwrite(text, sizeof(char), text_size, output_file); + if (bytes != text_size) { + printf("Warning: %d bytes written when %d bytes were expected\n", bytes, text_size); + } + fclose(output_file); + return NULL; +} + +void render_html(char* markdown_dir) { + int pf = MD_FLAG_COLLAPSEWHITESPACE | MD_FLAG_TABLES | MD_FLAG_TASKLISTS | MD_FLAG_STRIKETHROUGH | MD_FLAG_UNDERLINE; + int rf = 0; + + struct dirent* de; + DIR* dr = opendir(markdown_dir); + errno = 0; + if (dr == NULL) { + printf("Error: Couldn't open directory %s\n", markdown_dir); + exit(2); + } + while ((de = readdir(dr)) != NULL) { + switch (de->d_type) { + case DT_DIR: + render_html(de->d_name); + break; + case DT_REG: + md_html(input, strlen(input), process, NULL, pf, rf); + break; + } + } + if (errno != 0) { + printf("Warning: Error occured while scanning directory %s\n", markdown_dir); + } +} + +int main(int argv, char** argc) { + if (argv != 2) { + printf("Usage: ssg MARKDOWN_DIR\n"); + exit(1); + } +} diff --git a/c3/docs/.gitkeep b/c3/docs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/c3/lib/.gitkeep b/c3/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/c3/project.json b/c3/project.json new file mode 100644 index 0000000..878c800 --- /dev/null +++ b/c3/project.json @@ -0,0 +1,43 @@ +{ + // Language version of C3. + "langrev": "1", + // Warnings used for all targets. + "warnings": [ "no-unused" ], + // Directories where C3 library files may be found. + "dependency-search-paths": [ "lib" ], + // Libraries to use for all targets. + "dependencies": [ ], + // Authors, optionally with email. + "authors": [ "John Doe " ], + // Version using semantic versioning. + "version": "0.1.0", + // Sources compiled for all targets. + "sources": [ "src/**" ], + // Test sources compiled for all targets. + "test-sources": [ "test/**" ], + // C sources if the project also compiles C sources + // relative to the project file. + // "c-sources": [ "csource/**" ], + // Include directories for C sources relative to the project file. + // "c-include-dirs": [ "csource/include" ], + // Output location, relative to project file. + "output": "build", + // Architecture and OS target. + // You can use 'c3c --list-targets' to list all valid targets. + // "target": "windows-x64", + // Targets. + "targets": { + "ssg": { + // Executable or library. + "type": "executable", + // Additional libraries, sources + // and overrides of global settings here. + }, + }, + // Global settings. + // CPU name, used for optimizations in the LLVM backend. + "cpu": "generic", + // Optimization: "O0", "O1", "O2", "O3", "O4", "O5", "Os", "Oz". + "opt": "O0" + // See resources/examples/project_all_settings.json and 'c3c --list-project-properties' to see more properties. +} diff --git a/c3/resources/.gitkeep b/c3/resources/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/c3/scripts/.gitkeep b/c3/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/c3/src/.gitkeep b/c3/src/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/c3/src/main.c3 b/c3/src/main.c3 new file mode 100644 index 0000000..0cd31fd --- /dev/null +++ b/c3/src/main.c3 @@ -0,0 +1,8 @@ +module ssg; +import std::io; + +fn int main(String[] args) +{ + io::printn("Hello, World!"); + return 0; +} diff --git a/c3/test/.gitkeep b/c3/test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt new file mode 100644 index 0000000..dd8f701 --- /dev/null +++ b/cpp/CMakeLists.txt @@ -0,0 +1,34 @@ +# Almost all CMake files should start with this +# You should always specify a range with the newest +# and oldest tested versions of CMake. This will ensure +# you pick up the best policies. +cmake_minimum_required(VERSION 3.15...4.0) + +# This is your project statement. You should always list languages; +# Listing the version is nice here since it sets lots of useful variables +project( + ssg + VERSION 1.0 + LANGUAGES CXX) + +# If you set any CMAKE_ variables, that can go here. +# (But usually don't do this, except maybe for C++ standard) + +# Find packages go here. + +# You should usually split this into folders, but this is a simple example + +# This is a "default" library, and will match the *** variable setting. +# Other common choices are STATIC, SHARED, and MODULE +# Including header files here helps IDEs but is not required. +# Output libname matches target name, with the usual extensions on your system +# add_library(MyLibExample simple_lib.cpp simple_lib.hpp) + +# Link each target with other targets or add options, etc. + +# Adding something we can run - Output name matches target name +add_executable(ssg ssg.cpp) + +# Make sure you link your targets with this command. It can also link libraries and +# even flags, so linking a target that does not exist will not give a configure-time error. +target_link_libraries(ssg PRIVATE) diff --git a/cpp/ssg.cpp b/cpp/ssg.cpp new file mode 100644 index 0000000..a7903a6 --- /dev/null +++ b/cpp/ssg.cpp @@ -0,0 +1,13 @@ +// Necessary header files for input output functions +#include +using namespace std; + +// main() function: where the execution of +// C++ program begins +int main() { + + // This statement prints "Hello World" + cout << "Hello World"; + + return 0; +} diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 0000000..2f0c2b2 --- /dev/null +++ b/go/go.mod @@ -0,0 +1,3 @@ +module git.mchalupiak.com/ssg + +go 1.24.5 diff --git a/go/ssg.go b/go/ssg.go new file mode 100644 index 0000000..91e7378 --- /dev/null +++ b/go/ssg.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello World") +} diff --git a/hare/Makefile b/hare/Makefile new file mode 100644 index 0000000..7c87023 --- /dev/null +++ b/hare/Makefile @@ -0,0 +1,5 @@ +all: + hare build -o ssg ssg.ha #-lmd4c -lmd4c-html -O2 -Wall -o ssg + +run: all + ./ssg diff --git a/hare/ssg.ha b/hare/ssg.ha new file mode 100644 index 0000000..943c971 --- /dev/null +++ b/hare/ssg.ha @@ -0,0 +1,5 @@ +use fmt; + +export fn main() void = { + fmt::println("Hello world!")!; +}; diff --git a/markdown_files/intro.md b/markdown_files/intro.md new file mode 100644 index 0000000..a39f4b1 --- /dev/null +++ b/markdown_files/intro.md @@ -0,0 +1,17 @@ +# My Blog + +Welcome to *my* **blog**!. + +Here is a test list +- a +- b +- c +- d +- e + +Or numbered +1. a +2. b +3. c + +Thats it for now, will probably add more later diff --git a/nim/src/ssg.nim b/nim/src/ssg.nim new file mode 100644 index 0000000..862d40c --- /dev/null +++ b/nim/src/ssg.nim @@ -0,0 +1,5 @@ +# This is just an example to get you started. A typical binary package +# uses this file as the main entry point of the application. + +when isMainModule: + echo("Hello, World!") diff --git a/nim/ssg.nimble b/nim/ssg.nimble new file mode 100644 index 0000000..7d8f954 --- /dev/null +++ b/nim/ssg.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Michael Chalupiak" +description = "Static Site Generator in Nim" +license = "MIT" +srcDir = "src" +bin = @["ssg"] + + +# Dependencies + +requires "nim >= 2.2.4" diff --git a/odin/ssg.odin b/odin/ssg.odin new file mode 100644 index 0000000..7bbf860 --- /dev/null +++ b/odin/ssg.odin @@ -0,0 +1,7 @@ +package main + +import "core:fmt" + +main :: proc() { + fmt.println("Hellope!") +} diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..edeb9f9 --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ssg" +version = "0.1.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..d77273b --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ssg" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/rust/src/main.rs b/rust/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/rust/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/swift/Package.resolved b/swift/Package.resolved new file mode 100644 index 0000000..acf6375 --- /dev/null +++ b/swift/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "b2f9f80f764d5ceb785491044e6b20eace13f29886ee3a56c1f074ccc1039636", + "pins" : [ + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "309a47b2b1d9b5e991f36961c983ecec72275be3", + "version" : "1.6.1" + } + } + ], + "version" : 3 +} diff --git a/swift/Package.swift b/swift/Package.swift new file mode 100644 index 0000000..556e93c --- /dev/null +++ b/swift/Package.swift @@ -0,0 +1,21 @@ +// swift-tools-version: 6.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "ssg", + dependencies: [ + .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "ssg", + dependencies: [ + .product(name: "ArgumentParser", package: "swift-argument-parser"), + ] + ), + ] +) diff --git a/swift/Sources/ssg.swift b/swift/Sources/ssg.swift new file mode 100644 index 0000000..f0ecd86 --- /dev/null +++ b/swift/Sources/ssg.swift @@ -0,0 +1,14 @@ +// The Swift Programming Language +// https://docs.swift.org/swift-book +// +// Swift Argument Parser +// https://swiftpackageindex.com/apple/swift-argument-parser/documentation + +import ArgumentParser + +@main +struct ssg: ParsableCommand { + mutating func run() throws { + print("Hello, world!") + } +} diff --git a/zig/build.zig b/zig/build.zig new file mode 100644 index 0000000..8027d50 --- /dev/null +++ b/zig/build.zig @@ -0,0 +1,116 @@ +const std = @import("std"); + +// Although this function looks imperative, note that its job is to +// declaratively construct a build graph that will be executed by an external +// runner. +pub fn build(b: *std.Build) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard optimization options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not + // set a preferred release mode, allowing the user to decide how to optimize. + const optimize = b.standardOptimizeOption(.{}); + + // This creates a "module", which represents a collection of source files alongside + // some compilation options, such as optimization mode and linked system libraries. + // Every executable or library we compile will be based on one or more modules. + // const lib_mod = b.createModule(.{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + // .root_source_file = b.path("src/root.zig"), + // .target = target, + // .optimize = optimize, + // }); + + // We will also create a module for our other entry point, 'main.zig'. + const exe_mod = b.createModule(.{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + + // Modules can depend on one another using the `std.Build.Module.addImport` function. + // This is what allows Zig source code to use `@import("foo")` where 'foo' is not a + // file path. In this case, we set up `exe_mod` to import `lib_mod`. + // exe_mod.addImport("ssg_lib", lib_mod); + + // Now, we will create a static library based on the module we created above. + // This creates a `std.Build.Step.Compile`, which is the build step responsible + // for actually invoking the compiler. + // const lib = b.addLibrary(.{ + // .linkage = .static, + // .name = "ssg", + // .root_module = lib_mod, + // }); + + // This declares intent for the library to be installed into the standard + // location when the user invokes the "install" step (the default step when + // running `zig build`). + // b.installArtifact(lib); + + // This creates another `std.Build.Step.Compile`, but this one builds an executable + // rather than a static library. + const exe = b.addExecutable(.{ + .name = "ssg", + .root_module = exe_mod, + }); + + // This declares intent for the executable to be installed into the + // standard location when the user invokes the "install" step (the default + // step when running `zig build`). + b.installArtifact(exe); + + // This *creates* a Run step in the build graph, to be executed when another + // step is evaluated that depends on it. The next line below will establish + // such a dependency. + const run_cmd = b.addRunArtifact(exe); + + // By making the run step depend on the install step, it will be run from the + // installation directory rather than directly from within the cache directory. + // This is not necessary, however, if the application depends on other installed + // files, this ensures they will be present and in the expected location. + run_cmd.step.dependOn(b.getInstallStep()); + + // This allows the user to pass arguments to the application in the build + // command itself, like this: `zig build run -- arg1 arg2 etc` + if (b.args) |args| { + run_cmd.addArgs(args); + } + + // This creates a build step. It will be visible in the `zig build --help` menu, + // and can be selected like this: `zig build run` + // This will evaluate the `run` step rather than the default, which is "install". + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); + + // Creates a step for unit testing. This only builds the test executable + // but does not run it. + // const lib_unit_tests = b.addTest(.{ + // .root_module = lib_mod, + // }); + + // const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); + + const exe_unit_tests = b.addTest(.{ + .root_module = exe_mod, + }); + + const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + + // Similar to creating the run step earlier, this exposes a `test` step to + // the `zig build --help` menu, providing a way for the user to request + // running the unit tests. + const test_step = b.step("test", "Run unit tests"); + // test_step.dependOn(&run_lib_unit_tests.step); + test_step.dependOn(&run_exe_unit_tests.step); +} diff --git a/zig/build.zig.zon b/zig/build.zig.zon new file mode 100644 index 0000000..975cbac --- /dev/null +++ b/zig/build.zig.zon @@ -0,0 +1,86 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = .zig, + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.0.0", + + // Together with name, this represents a globally unique package + // identifier. This field is generated by the Zig toolchain when the + // package is first created, and then *never changes*. This allows + // unambiguous detection of one package being an updated version of + // another. + // + // When forking a Zig project, this id should be regenerated (delete the + // field and run `zig build`) if the upstream project is still maintained. + // Otherwise, the fork is *hostile*, attempting to take control over the + // original project's identity. Thus it is recommended to leave the comment + // on the following line intact, so that it shows up in code reviews that + // modify the field. + .fingerprint = 0xc1ce1081a0e36954, // Changing this has security and trust implications. + + // Tracks the earliest Zig version that the package considers to be a + // supported use case. + .minimum_zig_version = "0.14.1", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + // See `zig fetch --save ` for a command-line interface for adding dependencies. + //.example = .{ + // // When updating this field to a new URL, be sure to delete the corresponding + // // `hash`, otherwise you are communicating that you expect to find the old hash at + // // the new URL. If the contents of a URL change this will result in a hash mismatch + // // which will prevent zig from using it. + // .url = "https://example.com/foo.tar.gz", + // + // // This is computed from the file contents of the directory of files that is + // // obtained after fetching `url` and applying the inclusion rules given by + // // `paths`. + // // + // // This field is the source of truth; packages do not come from a `url`; they + // // come from a `hash`. `url` is just one of many possible mirrors for how to + // // obtain a package matching this `hash`. + // // + // // Uses the [multihash](https://multiformats.io/multihash/) format. + // .hash = "...", + // + // // When this is provided, the package is found in a directory relative to the + // // build root. In this case the package's hash is irrelevant and therefore not + // // computed. This field and `url` are mutually exclusive. + // .path = "foo", + // + // // When this is set to `true`, a package is declared to be lazily + // // fetched. This makes the dependency only get fetched if it is + // // actually used. + // .lazy = false, + //}, + }, + + // Specifies the set of files and directories that are included in this package. + // Only files and directories listed here are included in the `hash` that + // is computed for this package. Only files listed here will remain on disk + // when using the zig package manager. As a rule of thumb, one should list + // files required for compilation plus any license(s). + // Paths are relative to the build root. Use the empty string (`""`) to refer to + // the build root itself. + // A directory listed here means that all files within, recursively, are included. + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + // For example... + //"LICENSE", + //"README.md", + }, +} diff --git a/zig/src/main.zig b/zig/src/main.zig new file mode 100644 index 0000000..e8db093 --- /dev/null +++ b/zig/src/main.zig @@ -0,0 +1,39 @@ +//! By convention, main.zig is where your main function lives in the case that +//! you are building an executable. If you are making a library, the convention +//! is to delete this file and start with root.zig instead. + +pub fn main() !void { + // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) + std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); + + // stdout is for the actual output of your application, for example if you + // are implementing gzip, then only the compressed bytes should be sent to + // stdout, not any debugging messages. + const stdout_file = std.io.getStdOut().writer(); + var bw = std.io.bufferedWriter(stdout_file); + const stdout = bw.writer(); + + try stdout.print("Run `zig build test` to run the tests.\n", .{}); + + try bw.flush(); // Don't forget to flush! +} + +test "simple test" { + var list = std.ArrayList(i32).init(std.testing.allocator); + defer list.deinit(); // Try commenting this out and see if zig detects the memory leak! + try list.append(42); + try std.testing.expectEqual(@as(i32, 42), list.pop()); +} + +test "fuzz example" { + const Context = struct { + fn testOne(context: @This(), input: []const u8) anyerror!void { + _ = context; + // Try passing `--fuzz` to `zig build test` and see if it manages to fail this test case! + try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input)); + } + }; + try std.testing.fuzz(Context{}, Context.testOne, .{}); +} + +const std = @import("std");