Something went wrong. Try again.
Completely reimplimented in zig (eventually)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232const std = @import("std");const Session = @import("Session.zig");const style = @import("style.zig");const tools = @import("tools.zig");const PtgSession = @import("PtgSession.zig");const zli = @import("cli");
const File = std.Io.File;const Init = std.process.Init;
fn fail(init: Init, err: anyerror) !void { var err_buf: [256]u8 = undefined; var err_writer = File.stderr().writer(init.io, &err_buf); try style.errPrefix(init.io, &err_writer.interface); try err_writer.interface.print("{s}: {s}\n", .{ @errorName(err), ptgErrorHint(err) }); try err_writer.interface.flush(); std.process.exit(1);}
fn ptgErrorHint(err: anyerror) []const u8 { return switch (err) { error.NoActiveImage => "no active image set on tool", error.NameTooLong => "image name too long", error.ToolFailure => "tool rejected the request (is an image loaded?)", error.ToolProtocol, error.ToolBusy => "unexpected tool response", error.Timeout => "tool timed out", else => "communication with tool failed", };}
fn openSession(init: Init, serial: ?[]const u8) !Session { const info = try tools.findPickit5(init, serial); defer info.deinit(init.gpa);
var sess: Session = try .init( init.io, init.gpa, info.node, ); errdefer sess.deinit();
var out_buf: [4096]u8 = undefined; var out_writer = File.stdout().writer(init.io, &out_buf); try out_writer.interface.print( "Connecting to {s} ({s}, serial {s})\n", .{ info.name, info.node, info.serial }, ); try out_writer.interface.flush(); return sess;}
fn closeSession(sess: *Session) void { sess.deinit();}
fn run( init: Init, op: PtgSession.Op, image: ?[]const u8, serial: ?[]const u8,) !void { var out_buf: [4096]u8 = undefined; var out_writer = File.stdout().writer(init.io, &out_buf); const w = &out_writer.interface;
var sess = try openSession(init, serial); defer closeSession(&sess);
var tool: PtgSession = .init(init.gpa, &sess);
switch (op) { .list => { const entries = try tool.listImages(init.gpa); defer { for (entries) |entry| entry.deinit(init.gpa); init.gpa.free(entries); } if (entries.len == 0) { try w.print("No images on tool\n", .{}); } for (entries) |entry| { if (std.mem.eql(u8, entry.name, PtgSession.truncated_marker)) { try w.print("{s}\n", .{PtgSession.truncated_marker}); } else { try w.print( "{s}: {d} total, {d} pass\n", .{ entry.name, entry.total, entry.pass }, ); } } }, .active => { const name = try tool.getActiveImage(init.gpa); defer init.gpa.free(name); try w.print("{s}\n", .{name}); }, .set => { try tool.setActiveImage(image.?); try w.print("Active image: {s}\n", .{image.?}); }, .reset_stats => { try tool.resetStats(image.?); try w.print("Statistics reset: {s}\n", .{image.?}); }, .remove => { try tool.deleteImage(image.?); try w.print("Removed image: {s}\n", .{image.?}); }, }
try w.flush();}
const serial_param_doc = "Serial number of tool (required when multiple tools are attached)";
pub fn reset( init: Init, image: zli.Param( "image", []const u8, .required, "Image name", ), serial: zli.Param( "serial", ?[]const u8, .optional(null), serial_param_doc, ),) !void { run(init, .reset_stats, image.value, serial.value) catch |err| return fail(init, err);}
pub fn list( init: Init, serial: zli.Param( "serial", ?[]const u8, .optional(null), serial_param_doc, ),) !void { run(init, .list, null, serial.value) catch |err| return fail(init, err);}
pub fn active( init: Init, serial: zli.Param( "serial", ?[]const u8, .optional(null), serial_param_doc, ),) !void { run(init, .active, null, serial.value) catch |err| return fail(init, err);}
pub fn set( init: Init, image: zli.Param( "image", []const u8, .required, "Image name", ), serial: zli.Param( "serial", ?[]const u8, .optional(null), serial_param_doc, ),) !void { run(init, .set, image.value, serial.value) catch |err| return fail(init, err);}
pub fn remove( init: Init, image: zli.Param( "image", []const u8, .required, "Image name", ), serial: zli.Param( "serial", ?[]const u8, .optional(null), serial_param_doc, ),) !void { run(init, .remove, image.value, serial.value) catch |err| return fail(init, err);}
pub fn add( init: Init, name: zli.Param( "name", []const u8, .required, "Name to assign image", ), path: zli.Param( "path", []const u8, .required, "Path to image file", ),) !void { _ = name; _ = path; // MPLAB X does not upload a single image file: during a PTG program // cycle it builds a multi-file bundle on the tool (conf.ptg, // pm5Data.json, ptgdata, checksum) derived from the live programming // environment. Reproducing that bundle generator is still // unimplemented; see ProgrammerToGoImpl/Pm5PtgHandler in java_src. var err_buf: [512]u8 = undefined; var err_writer = File.stderr().writer(init.io, &err_buf); try style.errPrefix(init.io, &err_writer.interface); try err_writer.interface.writeAll( \\sending images is not implemented yet \\ MPLAB X builds PTG images from a live programming environment; this bundle generation is not reproduced yet. \\ ); try err_writer.interface.flush(); std.process.exit(1);}