Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ jobs:
uses: actions/checkout@v2

- name: Setup Zig
uses: mlugg/setup-zig@v1
with:
version: 0.14.0
uses: mlugg/setup-zig@v2

- name: Build Demo
run: |
Expand Down
114 changes: 59 additions & 55 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,38 @@ pub fn build(b: *std.Build) void {
const config = blk: {
var config = Config{};

add_config_option(b, &config, .read_only, "If set, the library will only be able to read filesystems.");
add_config_option(b, &config, .minimize, "Set this to different values to reduce API surface");
add_config_option(b, &config, .find, "Enable find support");
add_config_option(b, &config, .mkfs, "Enable mkfs support");
add_config_option(b, &config, .fastseek, "Use fast seek option");
add_config_option(b, &config, .expand, "Enables expandfs support");
add_config_option(b, &config, .chmod, "Enables chmod support");
add_config_option(b, &config, .label, "Enables support for handling of filesystem labels");
add_config_option(b, &config, .forward, "Enables forward support");
add_config_option(b, &config, .strfuncs, "Enables file string functions");
add_config_option(b, &config, .printf_lli, "Enables printf_lli support");
add_config_option(b, &config, .printf_float, "Enables printf_float support");
add_config_option(b, &config, .strf_encoding, "Sets the format string encoding");
add_config_option(b, &config, .max_long_name_len, "Sets the maximum name for long file names");
add_config_option(b, &config, .code_page, "Defines the OEM code page");
add_config_option(b, &config, .long_file_name, "Enables long file name support");
add_config_option(b, &config, .long_file_name_encoding, "Sets the encoding for long file names");
add_config_option(b, &config, .long_file_name_buffer_size, "Sets the buffer size for long file names");
add_config_option(b, &config, .short_file_name_buffer_size, "Sets the buffer size for short file names");
add_config_option(b, &config, .relative_path_api, "Enables the relative path API");
add_config_option(b, &config, .multi_partition, "Enables support for several partitions on the same drive");
add_config_option(b, &config, .lba64, "Enables support for 64 bit linear block addresses.");
add_config_option(b, &config, .min_gpt_sectors, "Sector count threshold for switching to GPT partition tables");
add_config_option(b, &config, .use_trim, "Enables support for ATA TRIM command");
add_config_option(b, &config, .tiny, "Enable tiny buffer configuration");
add_config_option(b, &config, .exfat, "Enables support for ExFAT");
add_config_option(b, &config, .filesystem_trust, "Sets which values in the FSINFO structure you trust.");
add_config_option(b, &config, .lock, "Enables file system locking");
add_config_option(b, &config, .reentrant, "Makes the library reentrant");
add_config_option(b, &config, .sync_type, "Defines the name of the C type which is used for sync operations");
add_config_option(b, &config, .timeout, "Defines the timeout period in OS ticks");
add_config_option(b, &config, "read_only", "If set, the library will only be able to read filesystems.");
add_config_option(b, &config, "minimize", "Set this to different values to reduce API surface");
add_config_option(b, &config, "find", "Enable find support");
add_config_option(b, &config, "mkfs", "Enable mkfs support");
add_config_option(b, &config, "fastseek", "Use fast seek option");
add_config_option(b, &config, "expand", "Enables expandfs support");
add_config_option(b, &config, "chmod", "Enables chmod support");
add_config_option(b, &config, "label", "Enables support for handling of filesystem labels");
add_config_option(b, &config, "forward", "Enables forward support");
add_config_option(b, &config, "strfuncs", "Enables file string functions");
add_config_option(b, &config, "printf_lli", "Enables printf_lli support");
add_config_option(b, &config, "printf_float", "Enables printf_float support");
add_config_option(b, &config, "strf_encoding", "Sets the format string encoding");
add_config_option(b, &config, "max_long_name_len", "Sets the maximum name for long file names");
add_config_option(b, &config, "code_page", "Defines the OEM code page");
add_config_option(b, &config, "long_file_name", "Enables long file name support");
add_config_option(b, &config, "long_file_name_encoding", "Sets the encoding for long file names");
add_config_option(b, &config, "long_file_name_buffer_size", "Sets the buffer size for long file names");
add_config_option(b, &config, "short_file_name_buffer_size", "Sets the buffer size for short file names");
add_config_option(b, &config, "relative_path_api", "Enables the relative path API");
add_config_option(b, &config, "maximum_path_depth", "Sets the maximum path depth");
add_config_option(b, &config, "multi_partition", "Enables support for several partitions on the same drive");
add_config_option(b, &config, "lba64", "Enables support for 64 bit linear block addresses.");
add_config_option(b, &config, "min_gpt_sectors", "Sector count threshold for switching to GPT partition tables");
add_config_option(b, &config, "use_trim", "Enables support for ATA TRIM command");
add_config_option(b, &config, "tiny", "Enable tiny buffer configuration");
add_config_option(b, &config, "exfat", "Enables support for ExFAT");
add_config_option(b, &config, "filesystem_trust", "Sets which values in the FSINFO structure you trust.");
add_config_option(b, &config, "lock", "Enables file system locking");
add_config_option(b, &config, "reentrant", "Makes the library reentrant");
add_config_option(b, &config, "sync_type", "Defines the name of the C type which is used for sync operations");
add_config_option(b, &config, "timeout", "Defines the timeout period in OS ticks");

const maybe_rtc_time = b.option([]const u8, "static-rtc", "Disables runtime time API by setting the clock to a fixed value. Provide a string in the format YYYY-MM-DD");
if (maybe_rtc_time) |rtc_time| {
Expand Down Expand Up @@ -91,13 +92,13 @@ pub fn build(b: *std.Build) void {
}

if (maybe_volume_names) |volume_names| {
var volumes = std.ArrayList([]const u8).init(b.allocator);
var volumes: std.ArrayList([]const u8) = .empty;

var iter = std.mem.splitScalar(u8, volume_names, ',');
while (iter.next()) |name| {
volumes.append(name) catch @panic("out of memory");
volumes.append(b.allocator, name) catch @panic("out of memory");
}
config.volumes = .{ .named = volumes.items };
config.volumes = .{ .named = volumes.toOwnedSlice(b.allocator) catch @panic("out of memory") };
}

const maybe_sector_config = b.option([]const u8, "sector-size", "Defines the sector size range. Use `<min>:<max>` or `<fixed>`. Valid items for the range are 512, 1024, 2048 or 4096. No other values allowed.");
Expand All @@ -109,20 +110,20 @@ pub fn build(b: *std.Build) void {
config.sector_size = .{
.dynamic = .{
.minimum = std.meta.stringToEnum(SectorOption, min) orelse bad_config(
"Invalid value for -Dsector-size: '{}'",
.{std.zig.fmtEscapes(sector_config)},
"Invalid value for -Dsector-size: '{f}'",
.{std.zig.fmtString(sector_config)},
),
.maximum = std.meta.stringToEnum(SectorOption, max) orelse bad_config(
"Invalid value for -Dsector-size: '{}'",
.{std.zig.fmtEscapes(sector_config)},
"Invalid value for -Dsector-size: '{f}'",
.{std.zig.fmtString(sector_config)},
),
},
};
} else {
config.sector_size = .{
.static = std.meta.stringToEnum(SectorOption, sector_config) orelse bad_config(
"Invalid value for -Dsector-size: '{}'",
.{std.zig.fmtEscapes(sector_config)},
"Invalid value for -Dsector-size: '{f}'",
.{std.zig.fmtString(sector_config)},
),
};
}
Expand All @@ -136,7 +137,7 @@ pub fn build(b: *std.Build) void {
.style = .blank,
.include_path = "ffconf.h",
}, .{
.FFCONF_DEF = 5380,
.FFCONF_DEF = 80386,
});

switch (config.volumes) {
Expand All @@ -147,19 +148,18 @@ pub fn build(b: *std.Build) void {
});
},
.named => |strings| {
var list = std.ArrayList(u8).init(b.allocator);
var list: std.Io.Writer.Allocating = .init(b.allocator);
for (strings) |name| {
if (list.items.len > 0) {
list.appendSlice(", ") catch @panic("out of memory");
if (list.written().len > 0) {
list.writer.writeAll(", ") catch @panic("out of memory");
}
list.writer().print("\"{}\"", .{
std.fmt.fmtSliceHexUpper(name),
}) catch @panic("out of memory");
list.writer.print("\"{X}\"", .{name}) catch @panic("out of memory");
}

config_header.addValues(.{
.FF_VOLUMES = @as(i64, @intCast(strings.len)),
.FF_STR_VOLUME_ID = 1,
.FF_VOLUME_STRS = list.items,
.FF_VOLUME_STRS = list.written(),
});
},
}
Expand Down Expand Up @@ -249,9 +249,11 @@ pub fn build(b: *std.Build) void {
// usage demo:
const exe = b.addExecutable(.{
.name = "zfat-demo",
.root_source_file = b.path("demo/main.zig"),
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.root_source_file = b.path("demo/main.zig"),
.target = target,
.optimize = optimize,
}),
});
exe.root_module.addImport("zfat", zfat_mod);

Expand Down Expand Up @@ -284,10 +286,10 @@ fn add_config_field(config_header: *std.Build.Step.ConfigHeader, config: Config,
}
}

fn add_config_option(b: *std.Build, config: *Config, comptime field: @TypeOf(.tag), desc: []const u8) void {
const T = std.meta.FieldType(Config, field);
if (b.option(T, @tagName(field), desc)) |value|
@field(config, @tagName(field)) = value;
fn add_config_option(b: *std.Build, config: *Config, comptime field: []const u8, desc: []const u8) void {
const T = @FieldType(Config, field);
if (b.option(T, field, desc)) |value|
@field(config, field) = value;
}

pub const Config = struct {
Expand All @@ -311,6 +313,7 @@ pub const Config = struct {
long_file_name_buffer_size: u32 = 255,
short_file_name_buffer_size: u32 = 12,
relative_path_api: RelativePathApi = .disabled,
maximum_path_depth: u8 = 10,
volumes: VolumeKind = .{ .count = 1 },
sector_size: SectorSize = .{ .static = .@"512" },
multi_partition: bool = false,
Expand Down Expand Up @@ -449,6 +452,7 @@ const macro_names = struct {
pub const long_file_name_buffer_size = "FF_LFN_BUF";
pub const short_file_name_buffer_size = "FF_SFN_BUF";
pub const relative_path_api = "FF_FS_RPATH";
pub const maximum_path_depth = "FF_PATH_DEPTH";
pub const multi_partition = "FF_MULTI_PARTITION";
pub const lba64 = "FF_LBA64";
pub const min_gpt_sectors = "FF_MIN_GPT";
Expand Down
7 changes: 4 additions & 3 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
.{
.name = .zfat,
.fingerprint = 0x4212c7b5f54ad348,
.version = "0.15.0",
.version = "0.16.0",
.minimum_zig_version = "0.15.1",
.dependencies = .{
.fatfs = .{
.url = "http://elm-chan.org/fsw/ff/arc/ff15a.zip",
.hash = "N-V-__8AAFQITQCnpmdR7PARImvk-cgb-9lZmjKolexSWkUL",
.url = "https://www.elm-chan.org/fsw/ff/arc/ff16.zip",
.hash = "N-V-__8AABFXTQB0pMbXIuSQik3qRrx7zxcVxvyIaM7n2nEd",
},
},
.paths = .{
Expand Down
9 changes: 6 additions & 3 deletions demo/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ pub fn main() !u8 {
var file = try fatfs.File.create("0:/firmware.uf2");
defer file.close();

try file.writer().writeAll("Hello, World!\r\n");
var buffer: [4096]u8 = undefined;
var writer = file.writer(&buffer);

try writer.interface.writeAll("Hello, World!\r\n");
}

return 0;
Expand Down Expand Up @@ -68,7 +71,7 @@ pub const Disk = struct {

std.log.info("read({*}, {}, {})", .{ buff, sector, count });

var sectors = std.io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
var sectors = std.Io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
sectors.seekTo(sector * sector_size) catch return error.IoError;
sectors.reader().readNoEof(buff[0 .. sector_size * count]) catch return error.IoError;
}
Expand All @@ -78,7 +81,7 @@ pub const Disk = struct {

std.log.info("write({*}, {}, {})", .{ buff, sector, count });

var sectors = std.io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
var sectors = std.Io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
sectors.seekTo(sector * sector_size) catch return error.IoError;
sectors.writer().writeAll(buff[0 .. sector_size * count]) catch return error.IoError;
}
Expand Down
Loading