llm
Download
49 lines 2 KiBCModified 2026-09-28 raw
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
// `tomo source`: inspect and extract the source archive embedded in compiled
// Tomo programs

#include "../stdlib/list.h"
#include "../stdlib/path.h"
#include "../stdlib/print.h"
#include "commands.h"
#include "common.h"
#include "compilation.h"

static List_t files = EMPTY_LIST;
static OptionalPath_t output = NULL;

static cli_arg_t source_spec[] = {
    {"files", &files, List$info(&Path$info), .positional = true, .required = true, .metavar = "binary",
     .description = "the compiled programs whose source archives to inspect"}, //
    {"output", &output, &Path$info, .short_flag = 'o', .metavar = "dest",
     .description = "unpack into this directory, or write the archive itself to this .zip file "
                    "(with no --output, the archive's contents are listed)"}, //
    VERBOSE_FLAG, //
};

static int cmd_source(cli_command_t *self, List_t extra_args) {
    (void)extra_args;
    set_default_logs(0);
    if (files.length == 0) print_err("No files provided!\n", self->usage);
    // Several binaries sharing one destination would overwrite each other,
    // and only the last one's sources would remain:
    if (output != NONE_PATH && files.length > 1)
        print_err("`--output` takes one binary's sources, but ", (int64_t)files.length, " binaries were given");
    // A destination named like a zip file (`-o ./src.zip`) gets the archive
    // itself; anything else is a directory to unpack into:
    bool as_zip = output != NONE_PATH && Path$has_extension(output, Text("zip"));
    for (int64_t i = 0; i < (int64_t)files.length; i++) {
        Path_t path = *(Path_t *)(files.data + i * files.stride);
        if (output == NONE_PATH) list_embedded_source(path);
        else if (as_zip) save_embedded_source_zip(path, output);
        else extract_embedded_source(path, output);
    }
    return 0;
}

cli_command_t source_command = {
    .name = "source",
    .summary = "List or extract the sources embedded in compiled programs",
    .spec_len = sizeof(source_spec) / sizeof(source_spec[0]),
    .spec = source_spec,
    .handler = cmd_source,
};