Adds justfile to build everything

This commit is contained in:
2026-02-13 23:20:36 +01:00
parent 27a3847c13
commit 00d9ce656c
17 changed files with 36 additions and 21 deletions

6
crates/bffs/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "bffs"
version = "0.1.0"
edition = "2024"
[dependencies]

3
crates/bffs/src/lib.rs Normal file
View File

@@ -0,0 +1,3 @@
#![no_std]
// const MAGIC_NUMBER: usize = 0xBFF5;

View File

@@ -0,0 +1,14 @@
[package]
name = "kernel-macros"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
image = "0.25"
regex = "1"
proc-macro2 = "1"
quote = "1"
syn = { version = "2", features = ["full"] }

View File

@@ -0,0 +1,106 @@
use image::{ImageBuffer, Luma};
use proc_macro::{Span, TokenStream};
use quote::quote;
use regex::Regex;
use syn::parse::Parse;
fn remove_non_alphanumeric(input: &str) -> String {
let re = Regex::new(r"[^a-zA-Z0-9_]+").unwrap();
re.replace_all(input, "").to_string()
}
fn to_format(img: ImageBuffer<Luma<u8>, Vec<u8>>, width: usize, height: usize) -> Vec<u8> {
let mut output = Vec::new();
let mut bit: u8 = 0;
let mut byte: u8 = 0;
for y in 0..height {
for x in 0..width {
let pixel = img.get_pixel(x as u32, y as u32)[0];
if pixel >= 127 {
byte |= 1 << bit;
}
bit += 1;
if bit == 8 {
output.push(byte);
byte = 0;
bit = 0;
}
}
}
if bit != 0 {
output.push(byte);
}
output
}
fn path_to_image(path: &str) -> (Vec<u8>, String, usize, usize) {
let img = match image::open(path) {
Ok(img) => img.to_luma8(),
Err(e) => panic!("failed to open image {}: {}", path, e),
};
let width = img.width() as usize;
let height = img.height() as usize;
let bytes = to_format(img, width, height);
let path = path
.split('/')
.next_back()
.expect("failed to get last part of path");
let split: Vec<_> = path.split('.').collect();
let name = remove_non_alphanumeric(&split[0..split.len() - 1].join(".")).to_uppercase();
(bytes, name, width, height)
}
struct ParsedArgs {
path: String,
}
impl Parse for ParsedArgs {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let path: syn::LitStr = input.parse()?;
let path = path.value();
Ok(ParsedArgs { path })
}
}
pub fn parse_image(
input: TokenStream,
) -> Result<
(
u8,
u8,
proc_macro2::Ident,
usize,
Vec<proc_macro2::TokenStream>,
),
syn::Error,
> {
// parse the input into a comma separated list of arguments
let parsed_args = syn::parse::<ParsedArgs>(input)?;
// let parsed_args = parse_macro_input!(input as ParsedArgs);
let (bytes, name, width, height) = path_to_image(&parsed_args.path);
let width = width as u8;
let height = height as u8;
let byte_array = bytes.as_slice();
let byte_count = byte_array.len();
let name_ident = syn::Ident::new(&name, Span::call_site().into());
let byte_tokens = bytes.iter().map(|b| quote! { #b }).collect::<Vec<_>>();
Ok((width, height, name_ident, byte_count, byte_tokens))
}
pub fn include_font_plate_impl(input: TokenStream) -> TokenStream {
let (_, _, _, _, byte_tokens) = parse_image(input).unwrap();
let output = quote! {
[#(#byte_tokens),*]
};
output.into()
}

View File

@@ -0,0 +1,8 @@
mod image;
use proc_macro::TokenStream;
#[proc_macro]
pub fn include_font_plate(input: TokenStream) -> TokenStream {
image::include_font_plate_impl(input)
}