First commit
Some checks failed
/ build (push) Failing after 4s
/ deploy (push) Has been skipped

This commit is contained in:
David Gonzalez Martin 2025-03-19 19:23:55 +01:00
commit 7760f4a754
42 changed files with 3280 additions and 0 deletions

35
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,35 @@
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
./build.sh
- name: Upload static files as artifact
id: deployment
uses: actions/upload-pages-artifact@v3
with:
path: public/
deploy:
needs: build
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# Specify runner + deployment step
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4 # or specific "vX.X.X" version tag for this action

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/index.html
/public/
/generate

8
build.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -eu
clang generate.c -o generate -std=gnu2x -g
./generate
rm -rf public || true
mkdir public
cp -r pdf public/pdf
cp index.html public/index.html

375
generate.c Normal file
View File

@ -0,0 +1,375 @@
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#define global_variable static
#define strlit_len(s) (sizeof(s) - 1)
#define strlit(s) (String){ .pointer = (u8*)(s), .length = strlit_len(s), }
#if _MSC_VER
#define trap() __fastfail(1)
#elif __has_builtin(__builtin_trap)
#define trap() __builtin_trap()
#else
extern BB_NORETURN BB_COLD void abort(void);
fn BB_NORETURN BB_COLD void trap_ext()
{
#ifdef __x86_64__
asm volatile("ud2");
#else
abort();
#endif
}
#define trap() (trap_ext(), __builtin_unreachable())
#endif
#ifndef BB_DEBUG
#define BB_DEBUG 1
#endif
#ifndef BB_SAFETY
#define BB_SAFETY BB_DEBUG
#endif
#define unused(x) (void)(x)
#if _MSC_VER
#define BB_NORETURN __declspec(noreturn)
#define BB_COLD __declspec(noinline)
#elif defined(__TINYC__)
#define BB_NORETURN __attribute__((noreturn))
#define BB_COLD __attribute__((cold))
#else
#define BB_NORETURN [[noreturn]]
#define BB_COLD [[gnu::cold]]
#endif
#if _MSC_VER
#define expect(x, b) (!!(x))
#else
#define expect(x, b) __builtin_expect(!!(x), b)
#endif
#define likely(x) expect(x, 1)
#define unlikely(x) expect(x, 0)
#define panic(format, ...) (os_exit(1))
#if BB_DEBUG
#define assert(x) (unlikely(!(x)) ? panic("Assert failed: \"" # x "\" at {cstr}:{u32}\n", __FILE__, __LINE__) : unused(0))
#else
#define assert(x) unused(likely(x))
#endif
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#define fn static
#define KB(n) ((n) * 1024)
#define MB(n) ((n) * 1024 * 1024)
#define GB(n) ((u64)(n) * 1024 * 1024 * 1024)
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
#define STRUCT_FORWARD_DECL(S) typedef struct S S
#define STRUCT(S) STRUCT_FORWARD_DECL(S); struct S
#define UNION_FORWARD_DECL(U) typedef union U U
#define UNION(U) UNION_FORWARD_DECL(U); union U
#define Slice(T) Slice_ ## T
#define SliceP(T) SliceP_ ## T
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
{\
T* pointer;\
u64 length;\
}
#define declare_slice(T) declare_slice_ex(T, Slice(T))
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
declare_slice(u8);
typedef Slice(u8) String;
#define VirtualBuffer(T) VirtualBuffer_ ## T
#define VirtualBufferP(T) VirtualBufferPointerTo_ ## T
#define decl_vb_ex(T, StructName) \
struct StructName \
{\
T* pointer;\
u32 length;\
u32 capacity;\
};\
typedef struct StructName StructName
#define decl_vb(T) decl_vb_ex(T, VirtualBuffer(T))
#define decl_vbp(T) decl_vb_ex(T*, VirtualBufferP(T))
decl_vb(u8);
decl_vbp(u8);
decl_vb(u16);
decl_vbp(u16);
decl_vb(u32);
decl_vbp(u32);
#define vb_size_of_element(vb) sizeof(*((vb)->pointer))
#define vb_add(vb, count) (typeof((vb)->pointer)) vb_generic_add((VirtualBuffer(u8)*)(vb), (vb_size_of_element(vb)), (count))
#define vb_add_scalar(vb, S) (S*) vb_generic_add(vb, 1, sizeof(S))
#define vb_copy_scalar(vb, s) *vb_add_scalar(vb, typeof(s)) = s
#define vb_append_struct(vb, T, s) *(vb_add_struct(vb, T)) = s
#define vb_append_one(vb, item) (typeof((vb)->pointer)) vb_generic_append((VirtualBuffer(u8)*)(vb), &(item), (vb_size_of_element(vb)), 1)
#define vb_to_bytes(vb) (Slice(u8)) { .pointer = (u8*)((vb).pointer), .length = (vb_size_of_element(vb)) * (vb).length, }
#define vb_ensure_capacity(vb, count) vb_generic_ensure_capacity((VirtualBuffer(u8)*)(vb), vb_size_of_element(vb), (count))
#define vb_copy_array(vb, arr) memcpy(vb_add(vb, array_length(arr)), arr, sizeof(arr))
#define vb_add_any_array(vb, E, count) (E*)vb_generic_add(vb, vb_size_of_element(vb), sizeof(E) * count)
#define vb_copy_any_array(vb, arr) memcpy(vb_generic_add(vb, vb_size_of_element(vb), sizeof(arr)), (arr), sizeof(arr))
#define vb_copy_any_slice(vb, slice) memcpy(vb_generic_add(vb, vb_size_of_element(vb), sizeof(*((slice).pointer)) * (slice).length), (slice).pointer, sizeof(*((slice).pointer)) * (slice).length)
fn void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count);
fn u8* vb_generic_add_assume_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count);
fn u8* vb_generic_add(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count);
fn u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes);
fn u32 vb_copy_string(VirtualBuffer(u8)* buffer, String string);
fn u64 vb_copy_string_zero_terminated(VirtualBuffer(u8)* buffer, String string);
STRUCT(OSReserveProtectionFlags)
{
u32 read:1;
u32 write:1;
u32 execute:1;
u32 reserved:29;
};
STRUCT(OSReserveMapFlags)
{
u32 priv:1;
u32 anon:1;
u32 noreserve:1;
u32 reserved:29;
};
#define let_pointer_cast(PointerChildType, var_name, value) PointerChildType* var_name = (PointerChildType*)(value)
#if defined(__TINYC__) || defined(_MSC_VER)
#define let(name, value) typeof(value) name = (value)
#else
#define let(name, value) __auto_type name = (value)
#endif
#define let_cast(T, name, value) T name = cast_to(T, value)
#define assign_cast(to, from) to = cast_to(typeof(to), from)
#define let_va_arg(T, name, args) T name = va_arg(args, T)
#define transmute(D, source) *(D*)&source
#if BB_SAFETY
#define cast_to(T, value) (assert((typeof(value)) (T) (value) == (value) && ((value) > 0) == ((T) (value) > 0)), (T) (value))
#else
#define cast_to(T, value) (T)(value)
#endif
#ifndef __APPLE__
#define MY_PAGE_SIZE KB(4)
#else
#define MY_PAGE_SIZE KB(16)
#endif
global_variable const u64 page_size = MY_PAGE_SIZE;
global_variable u64 minimum_granularity = MY_PAGE_SIZE;
// global_variable u64 middle_granularity = MB(2);
global_variable u64 default_size = GB(4);
fn u64 align_forward(u64 value, u64 alignment)
{
u64 mask = alignment - 1;
u64 result = (value + mask) & ~mask;
return result;
}
fn u8 os_is_being_debugged()
{
u8 result = 0;
#if _WIN32
result = IsDebuggerPresent() != 0;
#else
#ifdef __APPLE__
let(request, PT_TRACE_ME);
#else
let(request, PTRACE_TRACEME);
#endif
if (ptrace(request, 0, 0, 0) == -1)
{
let(error, errno);
if (error == EPERM)
{
result = 1;
}
}
#endif
return result;
}
BB_NORETURN BB_COLD fn void os_exit(u32 exit_code)
{
if (exit_code != 0 && os_is_being_debugged())
{
trap();
}
_exit(exit_code);
}
fn u8* os_reserve(u64 base, u64 size, OSReserveProtectionFlags protection, OSReserveMapFlags map)
{
#if _WIN32
DWORD map_flags = 0;
map_flags |= (MEM_RESERVE * map.noreserve);
DWORD protection_flags = 0;
protection_flags |= PAGE_READWRITE * (!protection.write && !protection.read);
protection_flags |= PAGE_READWRITE * (protection.write && protection.read);
protection_flags |= PAGE_READONLY * (protection.write && !protection.read);
return (u8*)VirtualAlloc((void*)base, size, map_flags, protection_flags);
#else
int protection_flags = (protection.read * PROT_READ) | (protection.write * PROT_WRITE) | (protection.execute * PROT_EXEC);
int map_flags = (map.anon * MAP_ANONYMOUS) | (map.priv * MAP_PRIVATE) | (map.noreserve * MAP_NORESERVE);
u8* result = (u8*)mmap((void*)base, size, protection_flags, map_flags, -1, 0);
assert(result != MAP_FAILED);
return result;
#endif
}
fn void os_commit(void* address, u64 size)
{
#if _WIN32
VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE);
#else
int result = mprotect(address, size, PROT_READ | PROT_WRITE);
assert(result == 0);
#endif
}
fn void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
{
u32 old_capacity = vb->capacity;
u32 wanted_capacity = vb->length + item_count;
if (old_capacity < wanted_capacity)
{
if (old_capacity == 0)
{
vb->pointer = os_reserve(0, item_size * UINT32_MAX, (OSReserveProtectionFlags) {}, (OSReserveMapFlags) { .priv = 1, .anon = 1, .noreserve = 1 });
}
let_cast(u32, old_page_capacity, align_forward(old_capacity * item_size, minimum_granularity));
let_cast(u32, new_page_capacity, align_forward(wanted_capacity * item_size, minimum_granularity));
let(commit_size, new_page_capacity - old_page_capacity);
void* commit_pointer = vb->pointer + old_page_capacity;
os_commit(commit_pointer, commit_size);
let(new_capacity, new_page_capacity / item_size);
vb->capacity = new_capacity;
}
}
fn u8* vb_generic_add_assume_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
{
u32 index = vb->length;
assert(vb->capacity >= index + item_count);
vb->length = index + item_count;
return vb->pointer + (index * item_size);
}
fn u8* vb_generic_add(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
{
vb_generic_ensure_capacity(vb, item_size, item_count);
return vb_generic_add_assume_capacity(vb, item_size, item_count);
}
fn u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
{
let_cast(u32, len, bytes.length);
vb_generic_ensure_capacity(vb, sizeof(u8), len);
let(pointer, vb_generic_add_assume_capacity(vb, sizeof(u8), len));
memcpy(pointer, bytes.pointer, len);
return pointer;
}
fn u32 vb_copy_string(VirtualBuffer(u8)* buffer, String string)
{
let(offset, buffer->length);
let_cast(u32, length, string.length);
let(pointer, vb_add(buffer, length));
memcpy(pointer, string.pointer, length);
return offset;
}
fn u64 vb_copy_string_zero_terminated(VirtualBuffer(u8)* buffer, String string)
{
assert(string.pointer[string.length] == 0);
string.length += 1;
vb_copy_string(buffer, string);
return string.length;
}
STRUCT(Writer)
{
VirtualBuffer(u8) buffer;
};
fn void write_line(Writer* writer, String string)
{
vb_copy_string(&writer->buffer, string);
*vb_add(&writer->buffer, 1) = '\n';
}
fn void write_head(Writer* writer)
{
write_line(writer, strlit("<head>"));
write_line(writer, strlit("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"));
write_line(writer, strlit("<title>David Gonzalez Martin</title>"));
write_line(writer, strlit("</head>"));
}
fn void write_body(Writer* writer)
{
write_line(writer, strlit("<body>"));
write_line(writer, strlit("Hola Marianita"));
write_line(writer, strlit("</body>"));
}
fn void html_start(Writer* writer)
{
write_line(writer, strlit("<!DOCTYPE html>"));
write_line(writer, strlit("<html lang=\"en\">"));
}
fn void html_end(Writer* writer)
{
write_line(writer, strlit("</html>"));
}
fn void write_document(Writer* writer)
{
html_start(writer);
write_head(writer);
write_body(writer);
html_end(writer);
}
int main()
{
int fd = open("index.html", O_TRUNC | O_WRONLY | O_CREAT, 0644);
assert(fd >= 0);
Writer writer = {};
write_document(&writer);
let(result, write(fd, writer.buffer.pointer, writer.buffer.length));
assert(result == writer.buffer.length);
close(fd);
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.