report cImport failure using textDocument/publishDiagnostics

This commit is contained in:
Techatrix
2022-09-19 19:53:41 +02:00
parent 7f4f002380
commit cf52fd8190
3 changed files with 120 additions and 98 deletions

View File

@@ -4,6 +4,7 @@ const Config = @import("Config.zig");
const ast = @import("ast.zig");
const Ast = std.zig.Ast;
const URI = @import("uri.zig");
const log = std.log.scoped(.translate_c);
/// converts a `@cInclude` node into an equivalent c header file
/// which can then be handed over to `zig translate-c`
@@ -92,24 +93,47 @@ fn convertCIncludeInternal(
}
}
pub const Result = union(enum) {
// uri to the generated zig file
success: []const u8,
// zig translate-c failed with the given stderr content
failure: []const u8,
pub fn deinit(self: *Result, allocator: std.mem.Allocator) void {
switch (self.*) {
.success => |path| allocator.free(path),
.failure => |stderr| allocator.free(stderr),
}
}
pub fn dupe(self: Result, allocator: std.mem.Allocator) !Result {
return switch (self) {
.success => |path| .{ .success = try allocator.dupe(u8, path) },
.failure => |stderr| .{ .failure = try allocator.dupe(u8, stderr) },
};
}
};
/// takes a c header file and returns the result from calling `zig translate-c`
/// returns the file path to the generated zig file
/// returns a URI to the generated zig file on success or the content of stderr on failure
/// null indicates a failure which is automatically logged
/// Caller owns returned memory.
pub fn translate(allocator: std.mem.Allocator, config: Config, include_dirs: []const []const u8, source: []const u8) error{OutOfMemory}!?[]const u8 {
pub fn translate(allocator: std.mem.Allocator, config: Config, include_dirs: []const []const u8, source: []const u8) error{OutOfMemory}!?Result {
const file_path = try std.fs.path.join(allocator, &[_][]const u8{ config.global_cache_path.?, "cimport.h" });
defer allocator.free(file_path);
var file = std.fs.createFileAbsolute(file_path, .{}) catch |err| {
std.log.warn("failed to create file '{s}': {}", .{ file_path, err });
log.warn("failed to create file '{s}': {}", .{ file_path, err });
return null;
};
defer file.close();
defer std.fs.deleteFileAbsolute(file_path) catch |err| {
std.log.warn("failed to delete file '{s}': {}", .{ file_path, err });
log.warn("failed to delete file '{s}': {}", .{ file_path, err });
};
_ = file.write(source) catch |err| {
std.log.warn("failed to write to '{s}': {}", .{ file_path, err });
log.warn("failed to write to '{s}': {}", .{ file_path, err });
return null;
};
const base_include_dirs = blk: {
@@ -161,7 +185,7 @@ pub fn translate(allocator: std.mem.Allocator, config: Config, include_dirs: []c
.allocator = allocator,
.argv = argv.items,
}) catch |err| {
std.log.err("Failed to execute zig translate-c process, error: {}", .{err});
log.err("Failed to execute zig translate-c process, error: {}", .{err});
return null;
};
@@ -170,14 +194,12 @@ pub fn translate(allocator: std.mem.Allocator, config: Config, include_dirs: []c
return switch (result.term) {
.Exited => |code| if (code == 0) {
return try allocator.dupe(u8, std.mem.sliceTo(result.stdout, '\n'));
return Result{ .success = try URI.fromPath(allocator, std.mem.sliceTo(result.stdout, '\n')) };
} else {
// TODO convert failure to `textDocument/publishDiagnostics`
std.log.err("zig translate-c process failed, code: {}, stderr: '{s}'", .{ code, result.stderr });
return null;
return Result{ .failure = try allocator.dupe(u8, std.mem.sliceTo(result.stderr, '\n')) };
},
else => {
std.log.err("zig translate-c process terminated '{}'", .{result.term});
log.err("zig translate-c process terminated '{}'", .{result.term});
return null;
},
};