amduat/src/tools/amduat_pel_cli.c

3634 lines
118 KiB
C
Raw Normal View History

#include "amduat/asl/asl_store_fs.h"
#include "amduat/asl/asl_store_fs_meta.h"
#include "amduat/asl/io.h"
#include "amduat/asl/parse.h"
#include "amduat/asl/ref_text.h"
#include "amduat/asl/store.h"
#include "amduat/enc/asl1_core_codec.h"
#include "amduat/enc/pel1_result.h"
#include "amduat/enc/pel_program_dag.h"
#include "amduat/enc/pel_trace_dag.h"
#include "amduat/hash/asl1.h"
#include "amduat/pel/opreg_kernel.h"
#include "amduat/pel/opreg_kernel_params.h"
#include "amduat/pel/program_dag_desc.h"
#include "amduat/pel/surf.h"
#include "amduat/util/hex.h"
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum {
AMDUAT_PEL_CLI_EXIT_OK = 0,
AMDUAT_PEL_CLI_EXIT_USAGE = 2,
AMDUAT_PEL_CLI_EXIT_IO = 3,
AMDUAT_PEL_CLI_EXIT_NOT_FOUND = 4,
AMDUAT_PEL_CLI_EXIT_STORE = 5,
AMDUAT_PEL_CLI_EXIT_UNSUPPORTED = 6,
AMDUAT_PEL_CLI_EXIT_CODEC = 7,
AMDUAT_PEL_CLI_EXIT_CONFIG = 8
};
static const char *const AMDUAT_PEL_CLI_DEFAULT_ROOT = ".amduat-asl";
typedef enum {
AMDUAT_PEL_CLI_REF_HEX = 0,
AMDUAT_PEL_CLI_REF_BYTES = 1
} amduat_pel_cli_ref_format_t;
typedef enum {
AMDUAT_PEL_CLI_FORMAT_TEXT = 0,
AMDUAT_PEL_CLI_FORMAT_JSON = 1
} amduat_pel_cli_output_format_t;
typedef enum {
AMDUAT_PEL_CLI_IO_RAW = 0,
AMDUAT_PEL_CLI_IO_ARTIFACT = 1
} amduat_pel_cli_io_format_t;
typedef struct {
const char *root;
amduat_pel_cli_ref_format_t ref_format;
amduat_pel_cli_output_format_t format;
bool quiet;
} amduat_pel_cli_global_opts_t;
static void amduat_pel_cli_print_usage(FILE *stream) {
fprintf(stream,
"usage:\n"
" amduat-pel [--root PATH] [--ref-format hex|bytes] [--format text|json]\n"
" [--quiet] <command> [args]\n"
"\n"
"commands:\n"
" run Execute a PEL/PROGRAM-DAG/1 program via PEL/1-SURF (store-backed).\n"
" exec Execute a PEL/PROGRAM-DAG/1 program in-memory (no store writes).\n"
" validate Validate a Program artifact (decode + DAG checks + params).\n"
" program Program DAG tools (decode, normalize).\n"
" trace Trace DAG tools (decode, from-result).\n"
" result Surface result tools (decode).\n"
" op Kernel op registry tools.\n"
" scheme Scheme refs, type tags, profile IDs.\n"
" help Show help for a command.\n"
"\n"
"global options:\n"
" --root PATH ASL store root (default .amduat-asl)\n"
" --ref-format hex|bytes Reference I/O format (default hex)\n"
" --format text|json Structured output format (default text)\n"
" --quiet Only print machine output\n"
"\n"
"run:\n"
" amduat-pel run --program-ref REF [--scheme-ref REF|dag]\n"
" [--input-ref REF ...] [--inputs-file PATH]\n"
" [--params-ref REF]\n"
" [--format text|json] [--ref-format hex|bytes]\n"
" Output: result_ref, trace_ref, output_refs (formatted per --format).\n"
"\n"
"exec:\n"
" amduat-pel exec --program PATH|-\n"
" [--input PATH ...] [--input-format raw|artifact]\n"
" [--output-dir DIR] [--output-format raw|artifact]\n"
" [--result-out PATH|-] [--format text|json]\n"
"\n"
"validate:\n"
" amduat-pel validate [--input PATH|- | --program-ref REF]\n"
" [--input-format raw|artifact]\n"
" [--expect-type-tag TAG]\n"
" [--format text|json]\n"
"\n"
"program:\n"
" amduat-pel program decode [--input PATH|- | --program-ref REF]\n"
" [--input-format raw|artifact]\n"
" [--expect-type-tag TAG]\n"
" [--format text|json]\n"
" amduat-pel program normalize --input PATH|- [--input-format raw|artifact]\n"
" [--output PATH|-] [--output-format raw|artifact]\n"
" [--type-tag TAG]\n"
"\n"
"trace:\n"
" amduat-pel trace decode [--input PATH|- | --trace-ref REF]\n"
" [--input-format raw|artifact]\n"
" [--expect-type-tag TAG]\n"
" [--format text|json]\n"
" amduat-pel trace from-result --result-ref REF [--root PATH]\n"
" [--format text|json]\n"
"\n"
"result:\n"
" amduat-pel result decode [--input PATH|- | --result-ref REF]\n"
" [--input-format raw|artifact]\n"
" [--expect-type-tag TAG]\n"
" [--format text|json]\n"
"\n"
"op:\n"
" amduat-pel op list [--format text|json]\n"
" amduat-pel op describe NAME[=VERSION] [--format text|json]\n"
" amduat-pel op params-decode --op NAME[=VERSION]\n"
" --input PATH|- [--format text|json]\n"
"\n"
"scheme:\n"
" amduat-pel scheme show [--format text|json]\n"
" amduat-pel scheme dag-ref [--format hex|bytes]\n"
"\n"
"defaults:\n"
" --root .amduat-asl\n"
" --ref-format hex\n"
" --input -\n"
" --output -\n"
" --input-format raw\n"
" --output-format raw\n"
" --scheme-ref dag\n"
"\n"
"notes:\n"
" - Only PEL/PROGRAM-DAG/1 is supported; other scheme refs yield SCHEME_UNSUPPORTED.\n"
" - Expected type tags: program 0x00000101, trace 0x00000102, result 0x00000103.\n"
" - Encoding profile IDs: program 0x0101, trace 0x0102, result 0x0103.\n"
" - Kernel ops: pel.bytes.concat, pel.bytes.slice, pel.bytes.const, pel.bytes.hash.asl1.\n"
" - --ref-format bytes expects --ref to be a path or '-' (raw reference bytes).\n");
}
static bool amduat_pel_cli_parse_ref_format(
const char *text,
amduat_pel_cli_ref_format_t *out_fmt) {
if (text == NULL || out_fmt == NULL) {
return false;
}
if (strcmp(text, "hex") == 0) {
*out_fmt = AMDUAT_PEL_CLI_REF_HEX;
return true;
}
if (strcmp(text, "bytes") == 0) {
*out_fmt = AMDUAT_PEL_CLI_REF_BYTES;
return true;
}
return false;
}
static bool amduat_pel_cli_parse_output_format(
const char *text,
amduat_pel_cli_output_format_t *out_fmt) {
if (text == NULL || out_fmt == NULL) {
return false;
}
if (strcmp(text, "text") == 0) {
*out_fmt = AMDUAT_PEL_CLI_FORMAT_TEXT;
return true;
}
if (strcmp(text, "json") == 0) {
*out_fmt = AMDUAT_PEL_CLI_FORMAT_JSON;
return true;
}
return false;
}
static bool amduat_pel_cli_parse_io_format(
const char *text,
amduat_pel_cli_io_format_t *out_fmt) {
if (text == NULL || out_fmt == NULL) {
return false;
}
if (strcmp(text, "raw") == 0) {
*out_fmt = AMDUAT_PEL_CLI_IO_RAW;
return true;
}
if (strcmp(text, "artifact") == 0) {
*out_fmt = AMDUAT_PEL_CLI_IO_ARTIFACT;
return true;
}
return false;
}
static const char *amduat_pel_cli_status_name(
amduat_pel_execution_status_t status) {
switch (status) {
case AMDUAT_PEL_EXEC_STATUS_OK:
return "OK";
case AMDUAT_PEL_EXEC_STATUS_SCHEME_UNSUPPORTED:
return "SCHEME_UNSUPPORTED";
case AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM:
return "INVALID_PROGRAM";
case AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS:
return "INVALID_INPUTS";
case AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED:
return "RUNTIME_FAILED";
default:
return "UNKNOWN";
}
}
static const char *amduat_pel_cli_error_kind_name(
amduat_pel_execution_error_kind_t kind) {
switch (kind) {
case AMDUAT_PEL_EXEC_ERROR_NONE:
return "NONE";
case AMDUAT_PEL_EXEC_ERROR_SCHEME:
return "SCHEME";
case AMDUAT_PEL_EXEC_ERROR_PROGRAM:
return "PROGRAM";
case AMDUAT_PEL_EXEC_ERROR_INPUTS:
return "INPUTS";
case AMDUAT_PEL_EXEC_ERROR_RUNTIME:
return "RUNTIME";
default:
return "UNKNOWN";
}
}
static const char *amduat_pel_cli_node_status_name(
amduat_pel_node_trace_status_t status) {
switch (status) {
case AMDUAT_PEL_NODE_TRACE_OK:
return "NODE_OK";
case AMDUAT_PEL_NODE_TRACE_FAILED:
return "NODE_FAILED";
case AMDUAT_PEL_NODE_TRACE_SKIPPED:
return "NODE_SKIPPED";
default:
return "NODE_UNKNOWN";
}
}
static const char *amduat_pel_cli_store_phase_name(
amduat_pel_store_failure_phase_t phase) {
switch (phase) {
case AMDUAT_PEL_STORE_FAILURE_PROGRAM:
return "PROGRAM";
case AMDUAT_PEL_STORE_FAILURE_INPUT:
return "INPUT";
default:
return "UNKNOWN";
}
}
static const char *amduat_pel_cli_store_error_name(
amduat_pel_store_error_code_t code) {
switch (code) {
case AMDUAT_PEL_STORE_ERROR_NOT_FOUND:
return "NOT_FOUND";
case AMDUAT_PEL_STORE_ERROR_INTEGRITY:
return "INTEGRITY";
case AMDUAT_PEL_STORE_ERROR_UNSUPPORTED:
return "UNSUPPORTED";
default:
return "UNKNOWN";
}
}
static const char *amduat_pel_cli_store_error_str(
amduat_asl_store_error_t err) {
switch (err) {
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
return "not found";
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
return "unsupported";
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
return "integrity";
case AMDUAT_ASL_STORE_OK:
return "ok";
default:
return "unknown";
}
}
static int amduat_pel_cli_map_store_error(amduat_asl_store_error_t err) {
switch (err) {
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
return AMDUAT_PEL_CLI_EXIT_NOT_FOUND;
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
return AMDUAT_PEL_CLI_EXIT_STORE;
case AMDUAT_ASL_STORE_OK:
default:
return AMDUAT_PEL_CLI_EXIT_STORE;
}
}
static void amduat_pel_cli_free_reference(amduat_reference_t *ref) {
if (ref == NULL) {
return;
}
free((void *)ref->digest.data);
ref->digest.data = NULL;
ref->digest.len = 0u;
}
static void amduat_pel_cli_free_artifact(amduat_artifact_t *artifact) {
if (artifact == NULL) {
return;
}
free((void *)artifact->bytes.data);
artifact->bytes.data = NULL;
artifact->bytes.len = 0u;
}
static void amduat_pel_cli_free_refs(amduat_reference_t *refs, size_t refs_len) {
size_t i;
if (refs == NULL) {
return;
}
for (i = 0; i < refs_len; ++i) {
amduat_pel_cli_free_reference(&refs[i]);
}
free(refs);
}
static bool amduat_pel_cli_read_path_once(const char *path,
bool *stdin_used,
uint8_t **out_bytes,
size_t *out_len) {
if (path == NULL || out_bytes == NULL || out_len == NULL) {
return false;
}
if (strcmp(path, "-") == 0 && stdin_used != NULL) {
if (*stdin_used) {
return false;
}
*stdin_used = true;
}
return amduat_asl_read_path(path, out_bytes, out_len);
}
static char *amduat_pel_cli_hex_encode(amduat_octets_t bytes) {
size_t out_len;
char *out;
out_len = amduat_hex_encoded_size(bytes.len);
out = (char *)malloc(out_len);
if (out == NULL) {
return NULL;
}
if (!amduat_hex_encode_lower(bytes.data, bytes.len, out, out_len)) {
free(out);
return NULL;
}
return out;
}
static bool amduat_pel_cli_ref_to_text(amduat_reference_t ref,
amduat_pel_cli_ref_format_t fmt,
char **out_text) {
if (out_text == NULL) {
return false;
}
*out_text = NULL;
if (fmt == AMDUAT_PEL_CLI_REF_HEX) {
return amduat_asl_ref_encode_hex(ref, out_text);
}
{
amduat_octets_t encoded;
char *hex;
if (!amduat_enc_asl1_core_encode_reference_v1(ref, &encoded)) {
return false;
}
hex = amduat_pel_cli_hex_encode(encoded);
free((void *)encoded.data);
if (hex == NULL) {
return false;
}
*out_text = hex;
return true;
}
}
static bool amduat_pel_cli_ref_from_text(const char *text,
amduat_pel_cli_ref_format_t fmt,
bool *stdin_used,
amduat_reference_t *out_ref) {
if (text == NULL || out_ref == NULL) {
return false;
}
memset(out_ref, 0, sizeof(*out_ref));
if (fmt == AMDUAT_PEL_CLI_REF_HEX) {
return amduat_asl_ref_decode_hex(text, out_ref);
}
{
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(text, stdin_used, &bytes, &len)) {
return false;
}
if (!amduat_asl_ref_decode_bytes(bytes, len, out_ref)) {
free(bytes);
return false;
}
free(bytes);
}
return true;
}
static bool amduat_pel_cli_append_ref(amduat_reference_t **refs,
size_t *refs_len,
amduat_reference_t ref) {
amduat_reference_t *next;
if (refs == NULL || refs_len == NULL) {
return false;
}
next = (amduat_reference_t *)realloc(
*refs, (*refs_len + 1u) * sizeof(**refs));
if (next == NULL) {
return false;
}
next[*refs_len] = ref;
*refs = next;
*refs_len += 1u;
return true;
}
static bool amduat_pel_cli_append_refs_from_file(
const char *path,
amduat_pel_cli_ref_format_t fmt,
bool *stdin_used,
amduat_reference_t **refs,
size_t *refs_len) {
uint8_t *bytes = NULL;
size_t len = 0;
size_t i = 0;
if (!amduat_pel_cli_read_path_once(path, stdin_used, &bytes, &len)) {
return false;
}
while (i < len) {
size_t start;
size_t token_len;
char *token;
amduat_reference_t ref;
while (i < len && isspace((unsigned char)bytes[i])) {
++i;
}
if (i >= len) {
break;
}
start = i;
while (i < len && !isspace((unsigned char)bytes[i])) {
++i;
}
token_len = i - start;
token = (char *)malloc(token_len + 1u);
if (token == NULL) {
free(bytes);
return false;
}
memcpy(token, bytes + start, token_len);
token[token_len] = '\0';
if (!amduat_pel_cli_ref_from_text(token, fmt, stdin_used, &ref)) {
free(token);
free(bytes);
return false;
}
free(token);
if (!amduat_pel_cli_append_ref(refs, refs_len, ref)) {
amduat_pel_cli_free_reference(&ref);
free(bytes);
return false;
}
}
free(bytes);
return true;
}
static void amduat_pel_cli_json_escape(FILE *stream,
const uint8_t *data,
size_t len) {
size_t i;
fputc('"', stream);
for (i = 0; i < len; ++i) {
uint8_t c = data[i];
switch (c) {
case '"':
fputs("\\\"", stream);
break;
case '\\':
fputs("\\\\", stream);
break;
case '\b':
fputs("\\b", stream);
break;
case '\f':
fputs("\\f", stream);
break;
case '\n':
fputs("\\n", stream);
break;
case '\r':
fputs("\\r", stream);
break;
case '\t':
fputs("\\t", stream);
break;
default:
if (c < 0x20) {
fprintf(stream, "\\u%04x", (unsigned int)c);
} else {
fputc((int)c, stream);
}
break;
}
}
fputc('"', stream);
}
static bool amduat_pel_cli_print_ref_text(FILE *stream,
amduat_reference_t ref,
amduat_pel_cli_ref_format_t fmt) {
char *ref_text = NULL;
if (!amduat_pel_cli_ref_to_text(ref, fmt, &ref_text)) {
return false;
}
fputs(ref_text, stream);
free(ref_text);
return true;
}
static bool amduat_pel_cli_print_ref_json(FILE *stream,
amduat_reference_t ref,
amduat_pel_cli_ref_format_t fmt) {
char *ref_text = NULL;
if (!amduat_pel_cli_ref_to_text(ref, fmt, &ref_text)) {
return false;
}
amduat_pel_cli_json_escape(stream,
(const uint8_t *)ref_text,
strlen(ref_text));
free(ref_text);
return true;
}
static bool amduat_pel_cli_parse_op_name(const char *text,
const char **out_name,
uint32_t *out_version) {
const char *eq;
if (text == NULL || out_name == NULL || out_version == NULL) {
return false;
}
eq = strchr(text, '=');
if (eq == NULL) {
*out_name = text;
*out_version = 1;
return true;
}
{
size_t name_len = (size_t)(eq - text);
char *name;
uint32_t version;
if (name_len == 0) {
return false;
}
if (!amduat_asl_parse_u32(eq + 1, &version)) {
return false;
}
name = (char *)malloc(name_len + 1u);
if (name == NULL) {
return false;
}
memcpy(name, text, name_len);
name[name_len] = '\0';
*out_name = name;
*out_version = version;
return true;
}
}
static void amduat_pel_cli_free_op_name(const char *name, const char *original) {
if (name != NULL && name != original) {
free((void *)name);
}
}
static bool amduat_pel_cli_print_program_text(
FILE *stream,
const amduat_pel_program_t *program) {
size_t i;
if (program == NULL) {
return false;
}
fprintf(stream, "nodes_len=%zu\n", program->nodes_len);
fprintf(stream, "roots_len=%zu\n", program->roots_len);
for (i = 0; i < program->nodes_len; ++i) {
const amduat_pel_node_t *node = &program->nodes[i];
size_t j;
char *params_hex;
fprintf(stream, "node[%zu].id=%u\n", i, node->id);
fprintf(stream, "node[%zu].op.name=%.*s\n", i,
(int)node->op.name.len,
node->op.name.data ? (const char *)node->op.name.data : "");
fprintf(stream, "node[%zu].op.version=%u\n", i, node->op.version);
fprintf(stream, "node[%zu].inputs_len=%zu\n", i, node->inputs_len);
for (j = 0; j < node->inputs_len; ++j) {
const amduat_pel_dag_input_t *input = &node->inputs[j];
if (input->kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
fprintf(stream, "node[%zu].input[%zu].kind=external\n", i, j);
fprintf(stream,
"node[%zu].input[%zu].external.input_index=%u\n",
i, j, input->value.external.input_index);
} else {
fprintf(stream, "node[%zu].input[%zu].kind=node\n", i, j);
fprintf(stream,
"node[%zu].input[%zu].node.node_id=%u\n",
i, j, input->value.node.node_id);
fprintf(stream,
"node[%zu].input[%zu].node.output_index=%u\n",
i, j, input->value.node.output_index);
}
}
params_hex = amduat_pel_cli_hex_encode(node->params);
if (params_hex == NULL) {
return false;
}
fprintf(stream, "node[%zu].params_len=%zu\n", i, node->params.len);
fprintf(stream, "node[%zu].params_hex=%s\n", i, params_hex);
free(params_hex);
}
for (i = 0; i < program->roots_len; ++i) {
fprintf(stream, "root[%zu].node_id=%u\n",
i, program->roots[i].node_id);
fprintf(stream, "root[%zu].output_index=%u\n",
i, program->roots[i].output_index);
}
return true;
}
static bool amduat_pel_cli_print_program_json(
FILE *stream,
const amduat_pel_program_t *program) {
size_t i;
if (program == NULL) {
return false;
}
fputs("{\"nodes\":[", stream);
for (i = 0; i < program->nodes_len; ++i) {
const amduat_pel_node_t *node = &program->nodes[i];
size_t j;
char *params_hex;
if (i != 0) {
fputc(',', stream);
}
fputs("{\"id\":", stream);
fprintf(stream, "%u", node->id);
fputs(",\"op\":{\"name\":", stream);
amduat_pel_cli_json_escape(stream,
node->op.name.data,
node->op.name.len);
fprintf(stream, ",\"version\":%u}", node->op.version);
fputs(",\"inputs\":[", stream);
for (j = 0; j < node->inputs_len; ++j) {
const amduat_pel_dag_input_t *input = &node->inputs[j];
if (j != 0) {
fputc(',', stream);
}
if (input->kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
fprintf(stream,
"{\"kind\":\"external\",\"input_index\":%u}",
input->value.external.input_index);
} else {
fprintf(stream,
"{\"kind\":\"node\",\"node_id\":%u,\"output_index\":%u}",
input->value.node.node_id,
input->value.node.output_index);
}
}
fputs("]", stream);
params_hex = amduat_pel_cli_hex_encode(node->params);
if (params_hex == NULL) {
return false;
}
fputs(",\"params_hex\":", stream);
amduat_pel_cli_json_escape(stream,
(const uint8_t *)params_hex,
strlen(params_hex));
free(params_hex);
fputs("}", stream);
}
fputs("],\"roots\":[", stream);
for (i = 0; i < program->roots_len; ++i) {
if (i != 0) {
fputc(',', stream);
}
fprintf(stream,
"{\"node_id\":%u,\"output_index\":%u}",
program->roots[i].node_id,
program->roots[i].output_index);
}
fputs("]}", stream);
return true;
}
static bool amduat_pel_cli_print_diagnostics_text(
FILE *stream,
const char *prefix,
const amduat_pel_diagnostic_entry_t *diags,
size_t diags_len) {
size_t i;
if (diags_len == 0) {
return true;
}
if (prefix == NULL) {
prefix = "";
}
for (i = 0; i < diags_len; ++i) {
char *msg_hex = amduat_pel_cli_hex_encode(diags[i].message);
if (msg_hex == NULL) {
return false;
}
fprintf(stream, "%sdiagnostic[%zu].code=%u\n", prefix, i, diags[i].code);
fprintf(stream, "%sdiagnostic[%zu].message_hex=%s\n",
prefix, i, msg_hex);
free(msg_hex);
}
return true;
}
static bool amduat_pel_cli_print_diagnostics_json(
FILE *stream,
const amduat_pel_diagnostic_entry_t *diags,
size_t diags_len) {
size_t i;
fputs("[", stream);
for (i = 0; i < diags_len; ++i) {
char *msg_hex = amduat_pel_cli_hex_encode(diags[i].message);
if (msg_hex == NULL) {
return false;
}
if (i != 0) {
fputc(',', stream);
}
fprintf(stream, "{\"code\":%u,\"message_hex\":", diags[i].code);
amduat_pel_cli_json_escape(stream,
(const uint8_t *)msg_hex,
strlen(msg_hex));
fputs("}", stream);
free(msg_hex);
}
fputs("]", stream);
return true;
}
static bool amduat_pel_cli_print_trace_text(
FILE *stream,
const amduat_pel_trace_dag_value_t *trace,
amduat_pel_cli_ref_format_t ref_format) {
size_t i;
if (trace == NULL) {
return false;
}
fprintf(stream, "pel1_version=%u\n", trace->pel1_version);
fprintf(stream, "scheme_ref=");
if (!amduat_pel_cli_print_ref_text(stream, trace->scheme_ref, ref_format)) {
return false;
}
fputc('\n', stream);
fprintf(stream, "program_ref=");
if (!amduat_pel_cli_print_ref_text(stream, trace->program_ref, ref_format)) {
return false;
}
fputc('\n', stream);
fprintf(stream, "status=%s(%u)\n",
amduat_pel_cli_status_name(trace->status),
(unsigned int)trace->status);
fprintf(stream, "error_kind=%s(%u)\n",
amduat_pel_cli_error_kind_name(trace->summary.kind),
(unsigned int)trace->summary.kind);
fprintf(stream, "status_code=%u\n",
(unsigned int)trace->summary.status_code);
fprintf(stream, "has_exec_result_ref=%s\n",
trace->has_exec_result_ref ? "true" : "false");
if (trace->has_exec_result_ref) {
fprintf(stream, "exec_result_ref=");
if (!amduat_pel_cli_print_ref_text(stream,
trace->exec_result_ref,
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "input_refs_len=%zu\n", trace->input_refs_len);
for (i = 0; i < trace->input_refs_len; ++i) {
fprintf(stream, "input_ref[%zu]=", i);
if (!amduat_pel_cli_print_ref_text(stream,
trace->input_refs[i],
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "has_params_ref=%s\n",
trace->has_params_ref ? "true" : "false");
if (trace->has_params_ref) {
fprintf(stream, "params_ref=");
if (!amduat_pel_cli_print_ref_text(stream,
trace->params_ref,
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "node_traces_len=%zu\n", trace->node_traces_len);
for (i = 0; i < trace->node_traces_len; ++i) {
const amduat_pel_node_trace_dag_t *node = &trace->node_traces[i];
size_t j;
fprintf(stream, "node_trace[%zu].node_id=%u\n", i, node->node_id);
fprintf(stream, "node_trace[%zu].op.name=%.*s\n", i,
(int)node->op_name.len,
node->op_name.data ? (const char *)node->op_name.data : "");
fprintf(stream, "node_trace[%zu].op.version=%u\n", i, node->op_version);
fprintf(stream, "node_trace[%zu].status=%s(%u)\n", i,
amduat_pel_cli_node_status_name(node->status),
(unsigned int)node->status);
fprintf(stream, "node_trace[%zu].status_code=%u\n", i,
node->status_code);
fprintf(stream, "node_trace[%zu].output_refs_len=%zu\n", i,
node->output_refs_len);
for (j = 0; j < node->output_refs_len; ++j) {
fprintf(stream, "node_trace[%zu].output_ref[%zu]=",
i, j);
if (!amduat_pel_cli_print_ref_text(stream,
node->output_refs[j],
ref_format)) {
return false;
}
fputc('\n', stream);
}
{
char prefix[64];
fprintf(stream, "node_trace[%zu].diagnostics_len=%zu\n", i,
node->diagnostics_len);
snprintf(prefix, sizeof(prefix), "node_trace[%zu].", i);
if (!amduat_pel_cli_print_diagnostics_text(
stream,
prefix,
node->diagnostics,
node->diagnostics_len)) {
return false;
}
}
}
return true;
}
static bool amduat_pel_cli_print_trace_json(
FILE *stream,
const amduat_pel_trace_dag_value_t *trace,
amduat_pel_cli_ref_format_t ref_format) {
size_t i;
if (trace == NULL) {
return false;
}
fputs("{\"pel1_version\":", stream);
fprintf(stream, "%u", trace->pel1_version);
fputs(",\"scheme_ref\":", stream);
if (!amduat_pel_cli_print_ref_json(stream, trace->scheme_ref, ref_format)) {
return false;
}
fputs(",\"program_ref\":", stream);
if (!amduat_pel_cli_print_ref_json(stream, trace->program_ref, ref_format)) {
return false;
}
fputs(",\"status\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_status_name(trace->status),
strlen(amduat_pel_cli_status_name(trace->status)));
fprintf(stream, ",\"status_code\":%u",
(unsigned int)trace->summary.status_code);
fputs(",\"error_kind\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_error_kind_name(trace->summary.kind),
strlen(amduat_pel_cli_error_kind_name(trace->summary.kind)));
fprintf(stream, ",\"error_kind_code\":%u",
(unsigned int)trace->summary.kind);
fputs(",\"has_exec_result_ref\":", stream);
fputs(trace->has_exec_result_ref ? "true" : "false", stream);
fputs(",\"exec_result_ref\":", stream);
if (trace->has_exec_result_ref) {
if (!amduat_pel_cli_print_ref_json(stream,
trace->exec_result_ref,
ref_format)) {
return false;
}
} else {
fputs("null", stream);
}
fputs(",\"input_refs\":[", stream);
for (i = 0; i < trace->input_refs_len; ++i) {
if (i != 0) {
fputc(',', stream);
}
if (!amduat_pel_cli_print_ref_json(stream,
trace->input_refs[i],
ref_format)) {
return false;
}
}
fputs("]", stream);
fputs(",\"has_params_ref\":", stream);
fputs(trace->has_params_ref ? "true" : "false", stream);
fputs(",\"params_ref\":", stream);
if (trace->has_params_ref) {
if (!amduat_pel_cli_print_ref_json(stream,
trace->params_ref,
ref_format)) {
return false;
}
} else {
fputs("null", stream);
}
fputs(",\"node_traces\":[", stream);
for (i = 0; i < trace->node_traces_len; ++i) {
const amduat_pel_node_trace_dag_t *node = &trace->node_traces[i];
size_t j;
if (i != 0) {
fputc(',', stream);
}
fprintf(stream, "{\"node_id\":%u,", node->node_id);
fputs("\"op\":{\"name\":", stream);
amduat_pel_cli_json_escape(stream, node->op_name.data, node->op_name.len);
fprintf(stream, ",\"version\":%u},", node->op_version);
fputs("\"status\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_node_status_name(node->status),
strlen(amduat_pel_cli_node_status_name(node->status)));
fprintf(stream, ",\"status_code\":%u", node->status_code);
fputs(",\"output_refs\":[", stream);
for (j = 0; j < node->output_refs_len; ++j) {
if (j != 0) {
fputc(',', stream);
}
if (!amduat_pel_cli_print_ref_json(stream,
node->output_refs[j],
ref_format)) {
return false;
}
}
fputs("],\"diagnostics\":", stream);
if (!amduat_pel_cli_print_diagnostics_json(stream,
node->diagnostics,
node->diagnostics_len)) {
return false;
}
fputs("}", stream);
}
fputs("]}", stream);
return true;
}
static bool amduat_pel_cli_print_result_text(
FILE *stream,
const amduat_pel_surface_execution_result_t *result,
amduat_pel_cli_ref_format_t ref_format) {
size_t i;
if (result == NULL) {
return false;
}
fprintf(stream, "pel1_version=%u\n", result->pel1_version);
fprintf(stream, "scheme_ref=");
if (!amduat_pel_cli_print_ref_text(stream, result->scheme_ref, ref_format)) {
return false;
}
fputc('\n', stream);
fprintf(stream, "program_ref=");
if (!amduat_pel_cli_print_ref_text(stream, result->program_ref, ref_format)) {
return false;
}
fputc('\n', stream);
fprintf(stream, "status=%s(%u)\n",
amduat_pel_cli_status_name(result->core_result.status),
(unsigned int)result->core_result.status);
fprintf(stream, "error_kind=%s(%u)\n",
amduat_pel_cli_error_kind_name(result->core_result.summary.kind),
(unsigned int)result->core_result.summary.kind);
fprintf(stream, "status_code=%u\n",
(unsigned int)result->core_result.summary.status_code);
if (!amduat_pel_cli_print_diagnostics_text(
stream,
"",
result->core_result.diagnostics,
result->core_result.diagnostics_len)) {
return false;
}
fprintf(stream, "input_refs_len=%zu\n", result->input_refs_len);
for (i = 0; i < result->input_refs_len; ++i) {
fprintf(stream, "input_ref[%zu]=", i);
if (!amduat_pel_cli_print_ref_text(stream,
result->input_refs[i],
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "output_refs_len=%zu\n", result->output_refs_len);
for (i = 0; i < result->output_refs_len; ++i) {
fprintf(stream, "output_ref[%zu]=", i);
if (!amduat_pel_cli_print_ref_text(stream,
result->output_refs[i],
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "has_params_ref=%s\n",
result->has_params_ref ? "true" : "false");
if (result->has_params_ref) {
fprintf(stream, "params_ref=");
if (!amduat_pel_cli_print_ref_text(stream,
result->params_ref,
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "has_trace_ref=%s\n",
result->has_trace_ref ? "true" : "false");
if (result->has_trace_ref) {
fprintf(stream, "trace_ref=");
if (!amduat_pel_cli_print_ref_text(stream,
result->trace_ref,
ref_format)) {
return false;
}
fputc('\n', stream);
}
fprintf(stream, "has_store_failure=%s\n",
result->has_store_failure ? "true" : "false");
if (result->has_store_failure) {
fprintf(stream, "store_failure.phase=%s(%u)\n",
amduat_pel_cli_store_phase_name(result->store_failure.phase),
(unsigned int)result->store_failure.phase);
fprintf(stream, "store_failure.error_code=%s(%u)\n",
amduat_pel_cli_store_error_name(result->store_failure.error_code),
(unsigned int)result->store_failure.error_code);
fprintf(stream, "store_failure.failing_ref=");
if (!amduat_pel_cli_print_ref_text(
stream, result->store_failure.failing_ref, ref_format)) {
return false;
}
fputc('\n', stream);
}
return true;
}
static bool amduat_pel_cli_print_result_json(
FILE *stream,
const amduat_pel_surface_execution_result_t *result,
amduat_pel_cli_ref_format_t ref_format) {
size_t i;
if (result == NULL) {
return false;
}
fputs("{\"pel1_version\":", stream);
fprintf(stream, "%u", result->pel1_version);
fputs(",\"scheme_ref\":", stream);
if (!amduat_pel_cli_print_ref_json(stream, result->scheme_ref, ref_format)) {
return false;
}
fputs(",\"program_ref\":", stream);
if (!amduat_pel_cli_print_ref_json(stream, result->program_ref, ref_format)) {
return false;
}
fputs(",\"status\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_status_name(result->core_result.status),
strlen(amduat_pel_cli_status_name(result->core_result.status)));
fprintf(stream, ",\"status_code\":%u",
(unsigned int)result->core_result.summary.status_code);
fputs(",\"error_kind\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_error_kind_name(
result->core_result.summary.kind),
strlen(amduat_pel_cli_error_kind_name(
result->core_result.summary.kind)));
fprintf(stream, ",\"error_kind_code\":%u",
(unsigned int)result->core_result.summary.kind);
fputs(",\"diagnostics\":", stream);
if (!amduat_pel_cli_print_diagnostics_json(
stream,
result->core_result.diagnostics,
result->core_result.diagnostics_len)) {
return false;
}
fputs(",\"input_refs\":[", stream);
for (i = 0; i < result->input_refs_len; ++i) {
if (i != 0) {
fputc(',', stream);
}
if (!amduat_pel_cli_print_ref_json(stream,
result->input_refs[i],
ref_format)) {
return false;
}
}
fputs("]", stream);
fputs(",\"output_refs\":[", stream);
for (i = 0; i < result->output_refs_len; ++i) {
if (i != 0) {
fputc(',', stream);
}
if (!amduat_pel_cli_print_ref_json(stream,
result->output_refs[i],
ref_format)) {
return false;
}
}
fputs("]", stream);
fputs(",\"has_params_ref\":", stream);
fputs(result->has_params_ref ? "true" : "false", stream);
fputs(",\"params_ref\":", stream);
if (result->has_params_ref) {
if (!amduat_pel_cli_print_ref_json(stream,
result->params_ref,
ref_format)) {
return false;
}
} else {
fputs("null", stream);
}
fputs(",\"has_trace_ref\":", stream);
fputs(result->has_trace_ref ? "true" : "false", stream);
fputs(",\"trace_ref\":", stream);
if (result->has_trace_ref) {
if (!amduat_pel_cli_print_ref_json(stream,
result->trace_ref,
ref_format)) {
return false;
}
} else {
fputs("null", stream);
}
fputs(",\"has_store_failure\":", stream);
fputs(result->has_store_failure ? "true" : "false", stream);
fputs(",\"store_failure\":", stream);
if (result->has_store_failure) {
fputs("{\"phase\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_store_phase_name(
result->store_failure.phase),
strlen(amduat_pel_cli_store_phase_name(result->store_failure.phase)));
fprintf(stream, ",\"phase_code\":%u",
(unsigned int)result->store_failure.phase);
fputs(",\"error_code\":", stream);
amduat_pel_cli_json_escape(
stream,
(const uint8_t *)amduat_pel_cli_store_error_name(
result->store_failure.error_code),
strlen(amduat_pel_cli_store_error_name(
result->store_failure.error_code)));
fprintf(stream, ",\"error_code_id\":%u",
(unsigned int)result->store_failure.error_code);
fputs(",\"failing_ref\":", stream);
if (!amduat_pel_cli_print_ref_json(stream,
result->store_failure.failing_ref,
ref_format)) {
return false;
}
fputs("}", stream);
} else {
fputs("null", stream);
}
fputs("}", stream);
return true;
}
static int amduat_pel_cli_cmd_run(int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *program_ref_text = NULL;
const char *scheme_ref_text = "dag";
const char *params_ref_text = NULL;
const char *inputs_file = NULL;
const char **input_ref_texts = NULL;
size_t input_ref_texts_len = 0;
amduat_pel_cli_ref_format_t ref_format;
amduat_pel_cli_output_format_t format;
const char *root;
bool quiet;
bool has_params_ref = false;
amduat_reference_t program_ref;
amduat_reference_t scheme_ref;
amduat_reference_t params_ref;
amduat_reference_t *input_refs = NULL;
size_t input_refs_len = 0;
amduat_reference_t *output_refs = NULL;
size_t output_refs_len = 0;
amduat_reference_t result_ref;
amduat_reference_t trace_ref;
amduat_artifact_t result_artifact;
amduat_pel_surface_execution_result_t result_value;
bool has_result_value = false;
bool has_trace_ref = false;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = global->root;
ref_format = global->ref_format;
format = global->format;
quiet = global->quiet;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--program-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --program-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
program_ref_text = argv[++i];
} else if (strcmp(argv[i], "--scheme-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --scheme-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
scheme_ref_text = argv[++i];
} else if (strcmp(argv[i], "--input-ref") == 0) {
const char **next;
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
next = (const char **)realloc(
input_ref_texts,
(input_ref_texts_len + 1u) * sizeof(*input_ref_texts));
if (next == NULL) {
fprintf(stderr, "error: out of memory\n");
return AMDUAT_PEL_CLI_EXIT_STORE;
}
input_ref_texts = next;
input_ref_texts[input_ref_texts_len++] = argv[++i];
} else if (strcmp(argv[i], "--inputs-file") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --inputs-file requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
inputs_file = argv[++i];
} else if (strcmp(argv[i], "--params-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --params-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
params_ref_text = argv[++i];
has_params_ref = true;
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--quiet") == 0) {
quiet = true;
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (program_ref_text == NULL) {
fprintf(stderr, "error: --program-ref is required\n");
free(input_ref_texts);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
free(input_ref_texts);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
free(input_ref_texts);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(program_ref_text,
ref_format,
&stdin_used,
&program_ref)) {
fprintf(stderr, "error: invalid --program-ref\n");
free(input_ref_texts);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (strcmp(scheme_ref_text, "dag") == 0) {
scheme_ref = amduat_pel_program_dag_scheme_ref();
} else if (!amduat_pel_cli_ref_from_text(scheme_ref_text,
ref_format,
&stdin_used,
&scheme_ref)) {
amduat_pel_cli_free_reference(&program_ref);
free(input_ref_texts);
fprintf(stderr, "error: invalid --scheme-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (has_params_ref) {
if (!amduat_pel_cli_ref_from_text(params_ref_text,
ref_format,
&stdin_used,
&params_ref)) {
amduat_pel_cli_free_reference(&program_ref);
if (strcmp(scheme_ref_text, "dag") != 0) {
amduat_pel_cli_free_reference(&scheme_ref);
}
free(input_ref_texts);
fprintf(stderr, "error: invalid --params-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
} else {
memset(&params_ref, 0, sizeof(params_ref));
}
for (i = 0; i < (int)input_ref_texts_len; ++i) {
amduat_reference_t ref;
if (!amduat_pel_cli_ref_from_text(input_ref_texts[i],
ref_format,
&stdin_used,
&ref)) {
fprintf(stderr, "error: invalid --input-ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
if (!amduat_pel_cli_append_ref(&input_refs, &input_refs_len, ref)) {
amduat_pel_cli_free_reference(&ref);
fprintf(stderr, "error: out of memory\n");
exit_code = AMDUAT_PEL_CLI_EXIT_STORE;
goto run_cleanup;
}
}
if (inputs_file != NULL) {
if (!amduat_pel_cli_append_refs_from_file(inputs_file,
ref_format,
&stdin_used,
&input_refs,
&input_refs_len)) {
fprintf(stderr, "error: failed to read inputs file\n");
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto run_cleanup;
}
}
memset(&result_ref, 0, sizeof(result_ref));
if (!amduat_pel_surf_run(&store,
scheme_ref,
program_ref,
input_refs,
input_refs_len,
has_params_ref,
params_ref,
&output_refs,
&output_refs_len,
&result_ref)) {
fprintf(stderr, "error: PEL surface execution failed\n");
exit_code = AMDUAT_PEL_CLI_EXIT_STORE;
goto run_cleanup;
}
memset(&trace_ref, 0, sizeof(trace_ref));
memset(&result_artifact, 0, sizeof(result_artifact));
if (amduat_asl_store_get(&store, result_ref, &result_artifact) ==
AMDUAT_ASL_STORE_OK) {
if (amduat_enc_pel1_result_decode_v1(result_artifact.bytes,
&result_value)) {
has_result_value = true;
if (result_value.has_trace_ref) {
trace_ref = result_value.trace_ref;
has_trace_ref = true;
}
}
}
if (!quiet) {
fprintf(stderr, "root=%s\n", root);
fprintf(stderr, "program_ref=");
if (!amduat_pel_cli_print_ref_text(stderr, program_ref, ref_format)) {
fprintf(stderr, "\n");
} else {
fputc('\n', stderr);
}
if (has_params_ref) {
fprintf(stderr, "params_ref=");
if (!amduat_pel_cli_print_ref_text(stderr, params_ref, ref_format)) {
fprintf(stderr, "\n");
} else {
fputc('\n', stderr);
}
}
if (has_result_value) {
fprintf(stderr, "status=%s(%u)\n",
amduat_pel_cli_status_name(result_value.core_result.status),
(unsigned int)result_value.core_result.status);
fprintf(stderr, "error_kind=%s(%u)\n",
amduat_pel_cli_error_kind_name(
result_value.core_result.summary.kind),
(unsigned int)result_value.core_result.summary.kind);
fprintf(stderr, "status_code=%u\n",
(unsigned int)result_value.core_result.summary.status_code);
}
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "result_ref=");
if (!amduat_pel_cli_print_ref_text(stdout, result_ref, ref_format)) {
fprintf(stderr, "error: failed to encode result ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
fputc('\n', stdout);
if (has_trace_ref) {
fprintf(stdout, "trace_ref=");
if (!amduat_pel_cli_print_ref_text(stdout, trace_ref, ref_format)) {
fprintf(stderr, "error: failed to encode trace ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
fputc('\n', stdout);
}
for (i = 0; i < (int)output_refs_len; ++i) {
fprintf(stdout, "output_ref[%d]=", i);
if (!amduat_pel_cli_print_ref_text(stdout,
output_refs[i],
ref_format)) {
fprintf(stderr, "error: failed to encode output ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
fputc('\n', stdout);
}
} else {
fputs("{\"ref_format\":\"", stdout);
fputs(ref_format == AMDUAT_PEL_CLI_REF_HEX ? "hex" : "bytes", stdout);
fputs("\",\"result_ref\":", stdout);
if (!amduat_pel_cli_print_ref_json(stdout, result_ref, ref_format)) {
fprintf(stderr, "error: failed to encode result ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
fputs(",\"trace_ref\":", stdout);
if (has_trace_ref) {
if (!amduat_pel_cli_print_ref_json(stdout, trace_ref, ref_format)) {
fprintf(stderr, "error: failed to encode trace ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
} else {
fputs("null", stdout);
}
fputs(",\"output_refs\":[", stdout);
for (i = 0; i < (int)output_refs_len; ++i) {
if (i != 0) {
fputc(',', stdout);
}
if (!amduat_pel_cli_print_ref_json(stdout,
output_refs[i],
ref_format)) {
fprintf(stderr, "error: failed to encode output ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto run_cleanup;
}
}
fputs("]}\n", stdout);
}
run_cleanup:
if (has_result_value) {
amduat_enc_pel1_result_free(&result_value);
}
if (output_refs != NULL) {
amduat_pel_surf_free_refs(output_refs, output_refs_len);
}
amduat_pel_surf_free_ref(&result_ref);
amduat_pel_cli_free_artifact(&result_artifact);
if (input_refs != NULL) {
amduat_pel_cli_free_refs(input_refs, input_refs_len);
}
if (has_params_ref) {
amduat_pel_cli_free_reference(&params_ref);
}
amduat_pel_cli_free_reference(&program_ref);
if (strcmp(scheme_ref_text, "dag") != 0) {
amduat_pel_cli_free_reference(&scheme_ref);
}
free(input_ref_texts);
return exit_code;
}
static int amduat_pel_cli_cmd_exec(int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *program_path = NULL;
const char **input_paths = NULL;
size_t input_paths_len = 0;
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_io_format_t output_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_output_format_t format;
const char *output_dir = ".";
const char *result_out = "-";
amduat_pel_program_t program;
amduat_artifact_t *inputs = NULL;
amduat_artifact_t *outputs = NULL;
size_t outputs_len = 0;
amduat_pel_execution_result_value_t result;
uint8_t *program_bytes = NULL;
size_t program_len = 0;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
FILE *out_stream = NULL;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--program") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --program requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
program_path = argv[++i];
} else if (strcmp(argv[i], "--input") == 0) {
const char **next;
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
next = (const char **)realloc(
input_paths, (input_paths_len + 1u) * sizeof(*input_paths));
if (next == NULL) {
fprintf(stderr, "error: out of memory\n");
return AMDUAT_PEL_CLI_EXIT_STORE;
}
input_paths = next;
input_paths[input_paths_len++] = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--output-dir") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --output-dir requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
output_dir = argv[++i];
} else if (strcmp(argv[i], "--output-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --output-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &output_format)) {
fprintf(stderr, "error: invalid output-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--result-out") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --result-out requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
result_out = argv[++i];
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (program_path == NULL) {
fprintf(stderr, "error: --program is required\n");
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_read_path_once(program_path,
&stdin_used,
&program_bytes,
&program_len)) {
fprintf(stderr, "error: failed to read program\n");
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_IO;
}
memset(&program, 0, sizeof(program));
if (!amduat_enc_pel_program_dag_decode_v1(
amduat_octets(program_bytes, program_len), &program)) {
fprintf(stderr, "error: invalid program encoding\n");
free(program_bytes);
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(program_bytes);
if (input_paths_len > 0) {
inputs = (amduat_artifact_t *)calloc(
input_paths_len, sizeof(*inputs));
if (inputs == NULL) {
fprintf(stderr, "error: out of memory\n");
amduat_enc_pel_program_dag_free(&program);
free(input_paths);
return AMDUAT_PEL_CLI_EXIT_STORE;
}
}
for (i = 0; i < (int)input_paths_len; ++i) {
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_paths[i],
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input: %s\n", input_paths[i]);
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &inputs[i])) {
free(bytes);
fprintf(stderr, "error: invalid input artifact\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto exec_cleanup;
}
free(bytes);
} else {
inputs[i] = amduat_artifact(amduat_octets(bytes, len));
}
}
if (!amduat_pel_program_dag_exec(&program,
inputs,
input_paths_len,
&outputs,
&outputs_len,
&result)) {
fprintf(stderr, "error: exec failed\n");
exit_code = AMDUAT_PEL_CLI_EXIT_STORE;
goto exec_cleanup;
}
for (i = 0; i < (int)outputs_len; ++i) {
char path_buf[4096];
if (snprintf(path_buf, sizeof(path_buf), "%s/output-%d",
output_dir, i) < 0) {
fprintf(stderr, "error: failed to build output path\n");
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
if (output_format == AMDUAT_PEL_CLI_IO_RAW) {
if (!amduat_asl_write_path(path_buf,
outputs[i].bytes.data,
outputs[i].bytes.len)) {
fprintf(stderr, "error: failed to write output: %s\n", path_buf);
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
} else {
amduat_octets_t encoded;
if (!amduat_enc_asl1_core_encode_artifact_v1(outputs[i], &encoded)) {
fprintf(stderr, "error: failed to encode output artifact\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
goto exec_cleanup;
}
if (!amduat_asl_write_path(path_buf, encoded.data, encoded.len)) {
fprintf(stderr, "error: failed to write output: %s\n", path_buf);
free((void *)encoded.data);
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
free((void *)encoded.data);
}
}
if (strcmp(result_out, "-") == 0) {
out_stream = stdout;
} else {
out_stream = fopen(result_out, "wb");
if (out_stream == NULL) {
fprintf(stderr, "error: failed to open result-out: %s\n", result_out);
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(out_stream, "status=%s(%u)\n",
amduat_pel_cli_status_name(result.status),
(unsigned int)result.status);
fprintf(out_stream, "error_kind=%s(%u)\n",
amduat_pel_cli_error_kind_name(result.summary.kind),
(unsigned int)result.summary.kind);
fprintf(out_stream, "status_code=%u\n",
(unsigned int)result.summary.status_code);
fprintf(out_stream, "outputs_len=%zu\n", outputs_len);
for (i = 0; i < (int)outputs_len; ++i) {
fprintf(out_stream, "output_path[%d]=%s/output-%d\n",
i, output_dir, i);
}
} else {
fputs("{\"status\":", out_stream);
amduat_pel_cli_json_escape(
out_stream,
(const uint8_t *)amduat_pel_cli_status_name(result.status),
strlen(amduat_pel_cli_status_name(result.status)));
fprintf(out_stream, ",\"status_code\":%u",
(unsigned int)result.summary.status_code);
fputs(",\"error_kind\":", out_stream);
amduat_pel_cli_json_escape(
out_stream,
(const uint8_t *)amduat_pel_cli_error_kind_name(result.summary.kind),
strlen(amduat_pel_cli_error_kind_name(result.summary.kind)));
fprintf(out_stream, ",\"error_kind_code\":%u",
(unsigned int)result.summary.kind);
fputs(",\"output_paths\":[", out_stream);
for (i = 0; i < (int)outputs_len; ++i) {
if (i != 0) {
fputc(',', out_stream);
}
{
char path_buf[4096];
if (snprintf(path_buf, sizeof(path_buf), "%s/output-%d",
output_dir, i) < 0) {
fprintf(stderr, "error: failed to build output path\n");
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
goto exec_cleanup;
}
amduat_pel_cli_json_escape(out_stream,
(const uint8_t *)path_buf,
strlen(path_buf));
}
}
fputs("]}\n", out_stream);
}
exec_cleanup:
if (out_stream != NULL && out_stream != stdout) {
fclose(out_stream);
}
if (outputs != NULL) {
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
}
if (inputs != NULL) {
for (i = 0; i < (int)input_paths_len; ++i) {
amduat_pel_cli_free_artifact(&inputs[i]);
}
free(inputs);
}
amduat_enc_pel_program_dag_free(&program);
free(input_paths);
return exit_code;
}
static int amduat_pel_cli_cmd_validate(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *input_path = "-";
const char *program_ref_text = NULL;
bool input_path_set = false;
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
const char *root;
bool has_expect_type_tag = false;
amduat_type_tag_t expect_type_tag;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
amduat_reference_t program_ref;
amduat_artifact_t artifact;
amduat_pel_program_t program;
bool stdin_used = false;
bool ok;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
root = global->root;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
input_path_set = true;
} else if (strcmp(argv[i], "--program-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --program-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
program_ref_text = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--expect-type-tag") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --expect-type-tag requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_parse_type_tag(argv[++i], &expect_type_tag)) {
fprintf(stderr, "error: invalid expect-type-tag\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
has_expect_type_tag = true;
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (program_ref_text != NULL && input_path_set) {
fprintf(stderr, "error: use --input or --program-ref\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
memset(&artifact, 0, sizeof(artifact));
if (program_ref_text != NULL) {
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(program_ref_text,
ref_format,
&stdin_used,
&program_ref)) {
fprintf(stderr, "error: invalid program-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
{
amduat_asl_store_error_t err =
amduat_asl_store_get(&store, program_ref, &artifact);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: store get failed: %s\n",
amduat_pel_cli_store_error_str(err));
amduat_pel_cli_free_reference(&program_ref);
return amduat_pel_cli_map_store_error(err);
}
}
amduat_pel_cli_free_reference(&program_ref);
} else {
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &artifact)) {
free(bytes);
fprintf(stderr, "error: invalid artifact encoding\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(bytes);
} else {
artifact = amduat_artifact(amduat_octets(bytes, len));
}
}
if (has_expect_type_tag) {
if (!artifact.has_type_tag ||
artifact.type_tag.tag_id != expect_type_tag.tag_id) {
fprintf(stderr, "error: type-tag mismatch\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
}
}
memset(&program, 0, sizeof(program));
ok = amduat_enc_pel_program_dag_decode_v1(artifact.bytes, &program);
if (!ok) {
fprintf(stderr, "error: invalid program encoding\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
ok = amduat_pel_program_dag_validate(&program);
amduat_enc_pel_program_dag_free(&program);
amduat_pel_cli_free_artifact(&artifact);
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "valid=%s\n", ok ? "true" : "false");
} else {
fprintf(stdout, "{\"valid\":%s}\n", ok ? "true" : "false");
}
if (!ok) {
exit_code = AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
}
return exit_code;
}
static int amduat_pel_cli_cmd_program_decode(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *input_path = "-";
const char *program_ref_text = NULL;
bool input_path_set = false;
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
const char *root;
bool has_expect_type_tag = false;
amduat_type_tag_t expect_type_tag;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
amduat_reference_t program_ref;
amduat_artifact_t artifact;
amduat_pel_program_t program;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
root = global->root;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
input_path_set = true;
} else if (strcmp(argv[i], "--program-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --program-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
program_ref_text = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--expect-type-tag") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --expect-type-tag requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_parse_type_tag(argv[++i], &expect_type_tag)) {
fprintf(stderr, "error: invalid expect-type-tag\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
has_expect_type_tag = true;
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (program_ref_text != NULL && input_path_set) {
fprintf(stderr, "error: use --input or --program-ref\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
memset(&artifact, 0, sizeof(artifact));
if (program_ref_text != NULL) {
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(program_ref_text,
ref_format,
&stdin_used,
&program_ref)) {
fprintf(stderr, "error: invalid program-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
{
amduat_asl_store_error_t err =
amduat_asl_store_get(&store, program_ref, &artifact);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: store get failed: %s\n",
amduat_pel_cli_store_error_str(err));
amduat_pel_cli_free_reference(&program_ref);
return amduat_pel_cli_map_store_error(err);
}
}
amduat_pel_cli_free_reference(&program_ref);
} else {
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &artifact)) {
free(bytes);
fprintf(stderr, "error: invalid artifact encoding\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(bytes);
} else {
artifact = amduat_artifact(amduat_octets(bytes, len));
}
}
if (has_expect_type_tag) {
if (!artifact.has_type_tag ||
artifact.type_tag.tag_id != expect_type_tag.tag_id) {
fprintf(stderr, "error: type-tag mismatch\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
}
}
memset(&program, 0, sizeof(program));
if (!amduat_enc_pel_program_dag_decode_v1(artifact.bytes, &program)) {
fprintf(stderr, "error: invalid program encoding\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
if (!amduat_pel_cli_print_program_text(stdout, &program)) {
fprintf(stderr, "error: failed to format program\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
} else {
if (!amduat_pel_cli_print_program_json(stdout, &program)) {
fprintf(stderr, "error: failed to format program\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
fputc('\n', stdout);
}
amduat_enc_pel_program_dag_free(&program);
amduat_pel_cli_free_artifact(&artifact);
return exit_code;
}
static int amduat_pel_cli_cmd_program_normalize(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *input_path = "-";
const char *output_path = "-";
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_io_format_t output_format = AMDUAT_PEL_CLI_IO_RAW;
bool has_type_tag = false;
amduat_type_tag_t type_tag;
amduat_artifact_t artifact;
amduat_pel_program_t program;
amduat_octets_t normalized;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
(void)global;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--output") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --output requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
output_path = argv[++i];
} else if (strcmp(argv[i], "--output-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --output-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &output_format)) {
fprintf(stderr, "error: invalid output-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--type-tag") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --type-tag requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_parse_type_tag(argv[++i], &type_tag)) {
fprintf(stderr, "error: invalid type-tag\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
has_type_tag = true;
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
memset(&artifact, 0, sizeof(artifact));
{
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &artifact)) {
free(bytes);
fprintf(stderr, "error: invalid artifact encoding\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(bytes);
} else {
artifact = amduat_artifact(amduat_octets(bytes, len));
}
}
memset(&program, 0, sizeof(program));
if (!amduat_enc_pel_program_dag_decode_v1(artifact.bytes, &program)) {
fprintf(stderr, "error: invalid program encoding\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
normalized = amduat_octets(NULL, 0);
if (!amduat_enc_pel_program_dag_encode_v1(&program, &normalized)) {
fprintf(stderr, "error: failed to normalize program\n");
amduat_enc_pel_program_dag_free(&program);
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (output_format == AMDUAT_PEL_CLI_IO_RAW) {
if (!amduat_asl_write_path(output_path,
normalized.data,
normalized.len)) {
fprintf(stderr, "error: failed to write output\n");
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
}
} else {
amduat_type_tag_t tag =
has_type_tag ? type_tag
: (artifact.has_type_tag
? artifact.type_tag
: amduat_type_tag(AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1));
amduat_artifact_t out_artifact =
amduat_artifact_with_type(normalized, tag);
amduat_octets_t encoded;
if (!amduat_enc_asl1_core_encode_artifact_v1(out_artifact, &encoded)) {
fprintf(stderr, "error: failed to encode output artifact\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
} else {
if (!amduat_asl_write_path(output_path, encoded.data, encoded.len)) {
fprintf(stderr, "error: failed to write output\n");
exit_code = AMDUAT_PEL_CLI_EXIT_IO;
}
free((void *)encoded.data);
}
}
free((void *)normalized.data);
amduat_enc_pel_program_dag_free(&program);
amduat_pel_cli_free_artifact(&artifact);
return exit_code;
}
static int amduat_pel_cli_cmd_program(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
if (argc < 1) {
fprintf(stderr, "error: program requires a subcommand\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "decode") == 0) {
return amduat_pel_cli_cmd_program_decode(argc - 1, argv + 1, global);
}
if (strcmp(argv[0], "normalize") == 0) {
return amduat_pel_cli_cmd_program_normalize(argc - 1, argv + 1, global);
}
fprintf(stderr, "error: unknown program subcommand: %s\n", argv[0]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
static int amduat_pel_cli_cmd_trace_decode(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *input_path = "-";
const char *trace_ref_text = NULL;
bool input_path_set = false;
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
const char *root;
bool has_expect_type_tag = false;
amduat_type_tag_t expect_type_tag;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
amduat_reference_t trace_ref;
amduat_artifact_t artifact;
amduat_pel_trace_dag_value_t trace;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
root = global->root;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
input_path_set = true;
} else if (strcmp(argv[i], "--trace-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --trace-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
trace_ref_text = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--expect-type-tag") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --expect-type-tag requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_parse_type_tag(argv[++i], &expect_type_tag)) {
fprintf(stderr, "error: invalid expect-type-tag\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
has_expect_type_tag = true;
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (trace_ref_text != NULL && input_path_set) {
fprintf(stderr, "error: use --input or --trace-ref\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
memset(&artifact, 0, sizeof(artifact));
if (trace_ref_text != NULL) {
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(trace_ref_text,
ref_format,
&stdin_used,
&trace_ref)) {
fprintf(stderr, "error: invalid trace-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
{
amduat_asl_store_error_t err =
amduat_asl_store_get(&store, trace_ref, &artifact);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: store get failed: %s\n",
amduat_pel_cli_store_error_str(err));
amduat_pel_cli_free_reference(&trace_ref);
return amduat_pel_cli_map_store_error(err);
}
}
amduat_pel_cli_free_reference(&trace_ref);
} else {
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &artifact)) {
free(bytes);
fprintf(stderr, "error: invalid artifact encoding\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(bytes);
} else {
artifact = amduat_artifact(amduat_octets(bytes, len));
}
}
if (has_expect_type_tag) {
if (!artifact.has_type_tag ||
artifact.type_tag.tag_id != expect_type_tag.tag_id) {
fprintf(stderr, "error: type-tag mismatch\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
}
}
memset(&trace, 0, sizeof(trace));
if (!amduat_enc_pel_trace_dag_decode_v1(artifact.bytes, &trace)) {
fprintf(stderr, "error: invalid trace encoding\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
if (!amduat_pel_cli_print_trace_text(stdout, &trace, ref_format)) {
fprintf(stderr, "error: failed to format trace\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
} else {
if (!amduat_pel_cli_print_trace_json(stdout, &trace, ref_format)) {
fprintf(stderr, "error: failed to format trace\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
fputc('\n', stdout);
}
amduat_enc_pel_trace_dag_free(&trace);
amduat_pel_cli_free_artifact(&artifact);
return exit_code;
}
static int amduat_pel_cli_cmd_trace_from_result(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *result_ref_text = NULL;
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
const char *root;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
amduat_reference_t result_ref;
amduat_artifact_t artifact;
amduat_pel_surface_execution_result_t result;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
root = global->root;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--result-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --result-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
result_ref_text = argv[++i];
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (result_ref_text == NULL) {
fprintf(stderr, "error: --result-ref is required\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(result_ref_text,
ref_format,
&stdin_used,
&result_ref)) {
fprintf(stderr, "error: invalid result-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
memset(&artifact, 0, sizeof(artifact));
{
amduat_asl_store_error_t err =
amduat_asl_store_get(&store, result_ref, &artifact);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: store get failed: %s\n",
amduat_pel_cli_store_error_str(err));
amduat_pel_cli_free_reference(&result_ref);
return amduat_pel_cli_map_store_error(err);
}
}
memset(&result, 0, sizeof(result));
if (!amduat_enc_pel1_result_decode_v1(artifact.bytes, &result)) {
fprintf(stderr, "error: invalid result encoding\n");
amduat_pel_cli_free_reference(&result_ref);
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "has_trace_ref=%s\n",
result.has_trace_ref ? "true" : "false");
fprintf(stdout, "trace_ref=");
if (result.has_trace_ref) {
if (!amduat_pel_cli_print_ref_text(stdout,
result.trace_ref,
ref_format)) {
fprintf(stderr, "error: failed to encode trace ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
}
fputc('\n', stdout);
} else {
fputs("{\"has_trace_ref\":", stdout);
fputs(result.has_trace_ref ? "true" : "false", stdout);
fputs(",\"trace_ref\":", stdout);
if (result.has_trace_ref) {
if (!amduat_pel_cli_print_ref_json(stdout,
result.trace_ref,
ref_format)) {
fprintf(stderr, "error: failed to encode trace ref\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
} else {
fputs("null", stdout);
}
fputs("}\n", stdout);
}
amduat_enc_pel1_result_free(&result);
amduat_pel_cli_free_reference(&result_ref);
amduat_pel_cli_free_artifact(&artifact);
return exit_code;
}
static int amduat_pel_cli_cmd_trace(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
if (argc < 1) {
fprintf(stderr, "error: trace requires a subcommand\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "decode") == 0) {
return amduat_pel_cli_cmd_trace_decode(argc - 1, argv + 1, global);
}
if (strcmp(argv[0], "from-result") == 0) {
return amduat_pel_cli_cmd_trace_from_result(argc - 1, argv + 1, global);
}
fprintf(stderr, "error: unknown trace subcommand: %s\n", argv[0]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
static int amduat_pel_cli_cmd_result_decode(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *input_path = "-";
const char *result_ref_text = NULL;
bool input_path_set = false;
amduat_pel_cli_io_format_t input_format = AMDUAT_PEL_CLI_IO_RAW;
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
const char *root;
bool has_expect_type_tag = false;
amduat_type_tag_t expect_type_tag;
amduat_asl_store_fs_config_t cfg;
amduat_asl_store_fs_t fs;
amduat_asl_store_t store;
amduat_reference_t result_ref;
amduat_artifact_t artifact;
amduat_pel_surface_execution_result_t result;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
root = global->root;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
input_path_set = true;
} else if (strcmp(argv[i], "--result-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --result-ref requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
result_ref_text = argv[++i];
} else if (strcmp(argv[i], "--input-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_io_format(argv[++i], &input_format)) {
fprintf(stderr, "error: invalid input-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--expect-type-tag") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --expect-type-tag requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_asl_parse_type_tag(argv[++i], &expect_type_tag)) {
fprintf(stderr, "error: invalid expect-type-tag\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
has_expect_type_tag = true;
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (result_ref_text != NULL && input_path_set) {
fprintf(stderr, "error: use --input or --result-ref\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
memset(&artifact, 0, sizeof(artifact));
if (result_ref_text != NULL) {
if (!amduat_asl_store_fs_load_config(root, &cfg)) {
fprintf(stderr, "error: failed to load store config: %s\n", root);
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_store_fs_init(&fs, cfg.config, root)) {
fprintf(stderr, "error: failed to initialize store\n");
return AMDUAT_PEL_CLI_EXIT_CONFIG;
}
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
if (!amduat_pel_cli_ref_from_text(result_ref_text,
ref_format,
&stdin_used,
&result_ref)) {
fprintf(stderr, "error: invalid result-ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
{
amduat_asl_store_error_t err =
amduat_asl_store_get(&store, result_ref, &artifact);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: store get failed: %s\n",
amduat_pel_cli_store_error_str(err));
amduat_pel_cli_free_reference(&result_ref);
return amduat_pel_cli_map_store_error(err);
}
}
amduat_pel_cli_free_reference(&result_ref);
} else {
uint8_t *bytes = NULL;
size_t len = 0;
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (input_format == AMDUAT_PEL_CLI_IO_ARTIFACT) {
if (!amduat_enc_asl1_core_decode_artifact_v1(
amduat_octets(bytes, len), &artifact)) {
free(bytes);
fprintf(stderr, "error: invalid artifact encoding\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
free(bytes);
} else {
artifact = amduat_artifact(amduat_octets(bytes, len));
}
}
if (has_expect_type_tag) {
if (!artifact.has_type_tag ||
artifact.type_tag.tag_id != expect_type_tag.tag_id) {
fprintf(stderr, "error: type-tag mismatch\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
}
}
memset(&result, 0, sizeof(result));
if (!amduat_enc_pel1_result_decode_v1(artifact.bytes, &result)) {
fprintf(stderr, "error: invalid result encoding\n");
amduat_pel_cli_free_artifact(&artifact);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
if (!amduat_pel_cli_print_result_text(stdout, &result, ref_format)) {
fprintf(stderr, "error: failed to format result\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
} else {
if (!amduat_pel_cli_print_result_json(stdout, &result, ref_format)) {
fprintf(stderr, "error: failed to format result\n");
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
}
fputc('\n', stdout);
}
amduat_enc_pel1_result_free(&result);
amduat_pel_cli_free_artifact(&artifact);
return exit_code;
}
static int amduat_pel_cli_cmd_result(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
if (argc < 1) {
fprintf(stderr, "error: result requires a subcommand\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "decode") == 0) {
return amduat_pel_cli_cmd_result_decode(argc - 1, argv + 1, global);
}
fprintf(stderr, "error: unknown result subcommand: %s\n", argv[0]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
static const struct {
const char *name;
uint32_t version;
} amduat_pel_cli_ops[] = {
{AMDUAT_PEL_KERNEL_OP_CONCAT_NAME, 1},
{AMDUAT_PEL_KERNEL_OP_SLICE_NAME, 1},
{AMDUAT_PEL_KERNEL_OP_CONST_NAME, 1},
{AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME, 1}
};
static const char *amduat_pel_cli_kernel_kind_name(
amduat_pel_kernel_op_kind_t kind) {
switch (kind) {
case AMDUAT_PEL_KERNEL_OP_CONCAT:
return "concat";
case AMDUAT_PEL_KERNEL_OP_SLICE:
return "slice";
case AMDUAT_PEL_KERNEL_OP_CONST:
return "const";
case AMDUAT_PEL_KERNEL_OP_HASH_ASL1:
return "hash_asl1";
default:
return "unknown";
}
}
static int amduat_pel_cli_cmd_op_list(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
amduat_pel_cli_output_format_t format;
size_t i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
for (i = 0; i < (size_t)argc; ++i) {
if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= (size_t)argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
for (i = 0; i < sizeof(amduat_pel_cli_ops) /
sizeof(amduat_pel_cli_ops[0]); ++i) {
fprintf(stdout, "name=%s version=%u\n",
amduat_pel_cli_ops[i].name,
amduat_pel_cli_ops[i].version);
}
} else {
fputs("{\"ops\":[", stdout);
for (i = 0; i < sizeof(amduat_pel_cli_ops) /
sizeof(amduat_pel_cli_ops[0]); ++i) {
if (i != 0) {
fputc(',', stdout);
}
fprintf(stdout, "{\"name\":");
amduat_pel_cli_json_escape(
stdout,
(const uint8_t *)amduat_pel_cli_ops[i].name,
strlen(amduat_pel_cli_ops[i].name));
fprintf(stdout, ",\"version\":%u}", amduat_pel_cli_ops[i].version);
}
fputs("]}\n", stdout);
}
return AMDUAT_PEL_CLI_EXIT_OK;
}
static int amduat_pel_cli_cmd_op_describe(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *op_text = NULL;
const char *op_name = NULL;
uint32_t op_version = 1;
amduat_pel_cli_output_format_t format;
const amduat_pel_kernel_op_desc_t *desc;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else if (op_text == NULL) {
op_text = argv[i];
} else {
fprintf(stderr, "error: unexpected argument: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (op_text == NULL) {
fprintf(stderr, "error: NAME[=VERSION] is required\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_op_name(op_text, &op_name, &op_version)) {
fprintf(stderr, "error: invalid op name\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
desc = amduat_pel_kernel_op_lookup(
amduat_octets(op_name, strlen(op_name)), op_version);
if (desc == NULL) {
fprintf(stderr, "error: op not found\n");
amduat_pel_cli_free_op_name(op_name, op_text);
return AMDUAT_PEL_CLI_EXIT_NOT_FOUND;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "name=%s\n", op_name);
fprintf(stdout, "version=%u\n", op_version);
fprintf(stdout, "kind=%s\n", amduat_pel_cli_kernel_kind_name(desc->kind));
fprintf(stdout, "kernel_op_code=0x%04x\n", desc->kernel_op_code);
fprintf(stdout, "min_inputs=%zu\n", desc->min_inputs);
fprintf(stdout, "max_inputs=%zu\n", desc->max_inputs);
fprintf(stdout, "outputs_len=%zu\n", desc->outputs_len);
} else {
fputs("{\"name\":", stdout);
amduat_pel_cli_json_escape(stdout,
(const uint8_t *)op_name,
strlen(op_name));
fprintf(stdout, ",\"version\":%u", op_version);
fputs(",\"kind\":", stdout);
amduat_pel_cli_json_escape(
stdout,
(const uint8_t *)amduat_pel_cli_kernel_kind_name(desc->kind),
strlen(amduat_pel_cli_kernel_kind_name(desc->kind)));
fprintf(stdout, ",\"kernel_op_code\":%u", desc->kernel_op_code);
fprintf(stdout, ",\"min_inputs\":%zu", desc->min_inputs);
fprintf(stdout, ",\"max_inputs\":%zu", desc->max_inputs);
fprintf(stdout, ",\"outputs_len\":%zu}\n", desc->outputs_len);
}
amduat_pel_cli_free_op_name(op_name, op_text);
return AMDUAT_PEL_CLI_EXIT_OK;
}
static int amduat_pel_cli_cmd_op_params_decode(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
const char *op_text = NULL;
const char *op_name = NULL;
uint32_t op_version = 1;
const char *input_path = NULL;
amduat_pel_cli_output_format_t format;
const amduat_pel_kernel_op_desc_t *desc;
amduat_pel_kernel_params_t params;
uint8_t *bytes = NULL;
size_t len = 0;
bool stdin_used = false;
int exit_code = AMDUAT_PEL_CLI_EXIT_OK;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--op") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --op requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
op_text = argv[++i];
} else if (strcmp(argv[i], "--input") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
input_path = argv[++i];
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (op_text == NULL || input_path == NULL) {
fprintf(stderr, "error: --op and --input are required\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_op_name(op_text, &op_name, &op_version)) {
fprintf(stderr, "error: invalid op name\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
desc = amduat_pel_kernel_op_lookup(
amduat_octets(op_name, strlen(op_name)), op_version);
if (desc == NULL) {
fprintf(stderr, "error: op not found\n");
amduat_pel_cli_free_op_name(op_name, op_text);
return AMDUAT_PEL_CLI_EXIT_NOT_FOUND;
}
if (!amduat_pel_cli_read_path_once(input_path,
&stdin_used,
&bytes,
&len)) {
fprintf(stderr, "error: failed to read input\n");
amduat_pel_cli_free_op_name(op_name, op_text);
return AMDUAT_PEL_CLI_EXIT_IO;
}
if (!amduat_pel_kernel_params_decode(
desc, amduat_octets(bytes, len), &params)) {
fprintf(stderr, "error: failed to decode params\n");
amduat_pel_cli_free_op_name(op_name, op_text);
free(bytes);
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "op=%s\n", op_name);
fprintf(stdout, "version=%u\n", op_version);
fprintf(stdout, "kind=%s\n", amduat_pel_cli_kernel_kind_name(params.kind));
switch (params.kind) {
case AMDUAT_PEL_KERNEL_OP_CONCAT:
fprintf(stdout, "params=unit\n");
break;
case AMDUAT_PEL_KERNEL_OP_SLICE:
fprintf(stdout, "offset=%" PRIu64 "\n",
(uint64_t)params.value.slice.offset);
fprintf(stdout, "length=%" PRIu64 "\n",
(uint64_t)params.value.slice.length);
break;
case AMDUAT_PEL_KERNEL_OP_CONST: {
char *hex = amduat_pel_cli_hex_encode(params.value.konst.bytes);
if (hex == NULL) {
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
break;
}
fprintf(stdout, "has_type_tag=%s\n",
params.value.konst.has_type_tag ? "true" : "false");
if (params.value.konst.has_type_tag) {
fprintf(stdout, "type_tag=0x%08x\n",
(unsigned int)params.value.konst.tag_id);
}
fprintf(stdout, "bytes_hex=%s\n", hex);
free(hex);
break;
}
case AMDUAT_PEL_KERNEL_OP_HASH_ASL1: {
const amduat_hash_asl1_desc_t *desc_hash =
amduat_hash_asl1_desc_lookup(params.value.hash.hash_id);
fprintf(stdout, "hash_id=0x%04x\n",
(unsigned int)params.value.hash.hash_id);
if (desc_hash != NULL && desc_hash->name != NULL) {
fprintf(stdout, "hash_name=%s\n", desc_hash->name);
}
break;
}
default:
break;
}
} else {
fputs("{\"op\":", stdout);
amduat_pel_cli_json_escape(stdout,
(const uint8_t *)op_name,
strlen(op_name));
fprintf(stdout, ",\"version\":%u", op_version);
fputs(",\"kind\":", stdout);
amduat_pel_cli_json_escape(
stdout,
(const uint8_t *)amduat_pel_cli_kernel_kind_name(params.kind),
strlen(amduat_pel_cli_kernel_kind_name(params.kind)));
switch (params.kind) {
case AMDUAT_PEL_KERNEL_OP_CONCAT:
fputs(",\"params\":null", stdout);
break;
case AMDUAT_PEL_KERNEL_OP_SLICE:
fprintf(stdout, ",\"offset\":%" PRIu64,
(uint64_t)params.value.slice.offset);
fprintf(stdout, ",\"length\":%" PRIu64,
(uint64_t)params.value.slice.length);
break;
case AMDUAT_PEL_KERNEL_OP_CONST: {
char *hex = amduat_pel_cli_hex_encode(params.value.konst.bytes);
if (hex == NULL) {
exit_code = AMDUAT_PEL_CLI_EXIT_CODEC;
break;
}
fputs(",\"has_type_tag\":", stdout);
fputs(params.value.konst.has_type_tag ? "true" : "false", stdout);
if (params.value.konst.has_type_tag) {
fprintf(stdout, ",\"type_tag\":%u", params.value.konst.tag_id);
} else {
fputs(",\"type_tag\":null", stdout);
}
fputs(",\"bytes_hex\":", stdout);
amduat_pel_cli_json_escape(stdout,
(const uint8_t *)hex,
strlen(hex));
free(hex);
break;
}
case AMDUAT_PEL_KERNEL_OP_HASH_ASL1: {
const amduat_hash_asl1_desc_t *desc_hash =
amduat_hash_asl1_desc_lookup(params.value.hash.hash_id);
fprintf(stdout, ",\"hash_id\":%u",
(unsigned int)params.value.hash.hash_id);
fputs(",\"hash_name\":", stdout);
if (desc_hash != NULL && desc_hash->name != NULL) {
amduat_pel_cli_json_escape(
stdout,
(const uint8_t *)desc_hash->name,
strlen(desc_hash->name));
} else {
fputs("null", stdout);
}
break;
}
default:
break;
}
fputs("}\n", stdout);
}
free(bytes);
amduat_pel_cli_free_op_name(op_name, op_text);
return exit_code;
}
static int amduat_pel_cli_cmd_op(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
if (argc < 1) {
fprintf(stderr, "error: op requires a subcommand\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "list") == 0) {
return amduat_pel_cli_cmd_op_list(argc - 1, argv + 1, global);
}
if (strcmp(argv[0], "describe") == 0) {
return amduat_pel_cli_cmd_op_describe(argc - 1, argv + 1, global);
}
if (strcmp(argv[0], "params-decode") == 0) {
return amduat_pel_cli_cmd_op_params_decode(argc - 1, argv + 1, global);
}
fprintf(stderr, "error: unknown op subcommand: %s\n", argv[0]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
static int amduat_pel_cli_cmd_scheme_show(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
amduat_pel_cli_output_format_t format;
amduat_pel_cli_ref_format_t ref_format;
amduat_reference_t scheme_ref;
int i;
if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
format = global->format;
ref_format = global->ref_format;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
scheme_ref = amduat_pel_program_dag_scheme_ref();
if (format == AMDUAT_PEL_CLI_FORMAT_TEXT) {
fprintf(stdout, "scheme_ref=");
if (!amduat_pel_cli_print_ref_text(stdout, scheme_ref, ref_format)) {
fprintf(stderr, "error: failed to encode scheme ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
fputc('\n', stdout);
fprintf(stdout, "program_type_tag=0x%08x\n",
AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1);
fprintf(stdout, "trace_type_tag=0x%08x\n",
AMDUAT_TYPE_TAG_PEL_TRACE_DAG_1);
fprintf(stdout, "result_type_tag=0x%08x\n",
AMDUAT_TYPE_TAG_PEL1_RESULT_1);
fprintf(stdout, "program_profile_id=0x%04x\n",
AMDUAT_PEL_ENC_PROGRAM_DAG_V1);
fprintf(stdout, "trace_profile_id=0x%04x\n",
AMDUAT_PEL_ENC_TRACE_DAG_V1);
fprintf(stdout, "result_profile_id=0x%04x\n",
AMDUAT_PEL_ENC_EXECUTION_RESULT_V1);
} else {
fputs("{\"scheme_ref\":", stdout);
if (!amduat_pel_cli_print_ref_json(stdout, scheme_ref, ref_format)) {
fprintf(stderr, "error: failed to encode scheme ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
fprintf(stdout, ",\"program_type_tag\":%u",
AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1);
fprintf(stdout, ",\"trace_type_tag\":%u",
AMDUAT_TYPE_TAG_PEL_TRACE_DAG_1);
fprintf(stdout, ",\"result_type_tag\":%u",
AMDUAT_TYPE_TAG_PEL1_RESULT_1);
fprintf(stdout, ",\"program_profile_id\":%u",
AMDUAT_PEL_ENC_PROGRAM_DAG_V1);
fprintf(stdout, ",\"trace_profile_id\":%u",
AMDUAT_PEL_ENC_TRACE_DAG_V1);
fprintf(stdout, ",\"result_profile_id\":%u}\n",
AMDUAT_PEL_ENC_EXECUTION_RESULT_V1);
}
return AMDUAT_PEL_CLI_EXIT_OK;
}
static int amduat_pel_cli_cmd_scheme_dag_ref(int argc, char **argv) {
amduat_pel_cli_ref_format_t fmt = AMDUAT_PEL_CLI_REF_HEX;
amduat_reference_t scheme_ref;
int i;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &fmt)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
scheme_ref = amduat_pel_program_dag_scheme_ref();
if (fmt == AMDUAT_PEL_CLI_REF_HEX) {
char *text = NULL;
if (!amduat_asl_ref_encode_hex(scheme_ref, &text)) {
fprintf(stderr, "error: failed to encode scheme ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
fputs(text, stdout);
fputc('\n', stdout);
free(text);
} else {
amduat_octets_t encoded;
if (!amduat_enc_asl1_core_encode_reference_v1(scheme_ref, &encoded)) {
fprintf(stderr, "error: failed to encode scheme ref\n");
return AMDUAT_PEL_CLI_EXIT_CODEC;
}
if (!amduat_asl_write_stream(stdout, encoded.data, encoded.len)) {
fprintf(stderr, "error: failed to write scheme ref\n");
free((void *)encoded.data);
return AMDUAT_PEL_CLI_EXIT_IO;
}
free((void *)encoded.data);
}
return AMDUAT_PEL_CLI_EXIT_OK;
}
static int amduat_pel_cli_cmd_scheme(
int argc,
char **argv,
const amduat_pel_cli_global_opts_t *global) {
if (argc < 1) {
fprintf(stderr, "error: scheme requires a subcommand\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "show") == 0) {
return amduat_pel_cli_cmd_scheme_show(argc - 1, argv + 1, global);
}
if (strcmp(argv[0], "dag-ref") == 0) {
return amduat_pel_cli_cmd_scheme_dag_ref(argc - 1, argv + 1);
}
fprintf(stderr, "error: unknown scheme subcommand: %s\n", argv[0]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
static int amduat_pel_cli_cmd_help(int argc, char **argv) {
(void)argc;
(void)argv;
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
}
int main(int argc, char **argv) {
amduat_pel_cli_global_opts_t global;
const char *command = NULL;
int i;
memset(&global, 0, sizeof(global));
global.root = AMDUAT_PEL_CLI_DEFAULT_ROOT;
global.ref_format = AMDUAT_PEL_CLI_REF_HEX;
global.format = AMDUAT_PEL_CLI_FORMAT_TEXT;
global.quiet = false;
for (i = 1; i < argc; ++i) {
if (argv[i][0] != '-') {
command = argv[i];
++i;
break;
}
if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
global.root = argv[++i];
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_ref_format(argv[++i], &global.ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --format requires a value\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (!amduat_pel_cli_parse_output_format(argv[++i], &global.format)) {
fprintf(stderr, "error: invalid format\n");
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--quiet") == 0) {
global.quiet = true;
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
amduat_pel_cli_print_usage(stdout);
return AMDUAT_PEL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
}
if (command == NULL) {
fprintf(stderr, "error: command required\n");
amduat_pel_cli_print_usage(stderr);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}
if (strcmp(command, "run") == 0) {
return amduat_pel_cli_cmd_run(argc - i, argv + i, &global);
}
if (strcmp(command, "exec") == 0) {
return amduat_pel_cli_cmd_exec(argc - i, argv + i, &global);
}
if (strcmp(command, "validate") == 0) {
return amduat_pel_cli_cmd_validate(argc - i, argv + i, &global);
}
if (strcmp(command, "program") == 0) {
return amduat_pel_cli_cmd_program(argc - i, argv + i, &global);
}
if (strcmp(command, "trace") == 0) {
return amduat_pel_cli_cmd_trace(argc - i, argv + i, &global);
}
if (strcmp(command, "result") == 0) {
return amduat_pel_cli_cmd_result(argc - i, argv + i, &global);
}
if (strcmp(command, "op") == 0) {
return amduat_pel_cli_cmd_op(argc - i, argv + i, &global);
}
if (strcmp(command, "scheme") == 0) {
return amduat_pel_cli_cmd_scheme(argc - i, argv + i, &global);
}
if (strcmp(command, "help") == 0) {
return amduat_pel_cli_cmd_help(argc - i, argv + i);
}
fprintf(stderr, "error: unknown command: %s\n", command);
amduat_pel_cli_print_usage(stderr);
return AMDUAT_PEL_CLI_EXIT_USAGE;
}