815 lines
26 KiB
C
815 lines
26 KiB
C
#include "amduat/format/pel.h"
|
|
|
|
#include "amduat/format/json.h"
|
|
#include "amduat/format/ref.h"
|
|
#include "amduat/util/hex.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
const char *amduat_format_pel_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";
|
|
}
|
|
}
|
|
|
|
const char *amduat_format_pel_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";
|
|
}
|
|
}
|
|
|
|
const char *amduat_format_pel_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";
|
|
}
|
|
}
|
|
|
|
const char *amduat_format_pel_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";
|
|
}
|
|
}
|
|
|
|
const char *amduat_format_pel_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";
|
|
}
|
|
}
|
|
|
|
const char *amduat_format_pel_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 char *amduat_format_hex_encode(amduat_octets_t bytes) {
|
|
char *hex = NULL;
|
|
if (!amduat_hex_encode_alloc(bytes.data, bytes.len, &hex)) {
|
|
return NULL;
|
|
}
|
|
return hex;
|
|
}
|
|
|
|
static bool amduat_is_printable_ascii(amduat_octets_t bytes) {
|
|
size_t i;
|
|
|
|
if (bytes.len == 0) {
|
|
return true;
|
|
}
|
|
if (bytes.data == NULL) {
|
|
return false;
|
|
}
|
|
for (i = 0; i < bytes.len; ++i) {
|
|
uint8_t c = bytes.data[i];
|
|
if (c < 0x20u || c > 0x7eu) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool amduat_format_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_format_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);
|
|
if (amduat_is_printable_ascii(diags[i].message)) {
|
|
fprintf(stream, "%sdiagnostic[%zu].message=%.*s\n",
|
|
prefix, i, (int)diags[i].message.len,
|
|
(const char *)diags[i].message.data);
|
|
}
|
|
free(msg_hex);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool amduat_format_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_format_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);
|
|
if (!amduat_format_json_escape(
|
|
stream, amduat_octets(msg_hex, strlen(msg_hex)))) {
|
|
free(msg_hex);
|
|
return false;
|
|
}
|
|
if (amduat_is_printable_ascii(diags[i].message)) {
|
|
fputs(",\"message\":", stream);
|
|
if (!amduat_format_json_escape(stream, diags[i].message)) {
|
|
free(msg_hex);
|
|
return false;
|
|
}
|
|
}
|
|
fputs("}", stream);
|
|
free(msg_hex);
|
|
}
|
|
fputs("]", stream);
|
|
return true;
|
|
}
|
|
|
|
static bool amduat_format_program_text(FILE *stream,
|
|
const amduat_pel_program_t *program) {
|
|
size_t i;
|
|
|
|
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_format_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_format_program_json(FILE *stream,
|
|
const amduat_pel_program_t *program) {
|
|
size_t i;
|
|
|
|
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);
|
|
if (!amduat_format_json_escape(stream, node->op.name)) {
|
|
return false;
|
|
}
|
|
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_format_hex_encode(node->params);
|
|
if (params_hex == NULL) {
|
|
return false;
|
|
}
|
|
fputs(",\"params_hex\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream, amduat_octets(params_hex, strlen(params_hex)))) {
|
|
free(params_hex);
|
|
return false;
|
|
}
|
|
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;
|
|
}
|
|
|
|
bool amduat_format_pel_program(FILE *stream,
|
|
const amduat_pel_program_t *program,
|
|
amduat_format_output_t format) {
|
|
if (stream == NULL || program == NULL) {
|
|
return false;
|
|
}
|
|
if (format == AMDUAT_FORMAT_OUTPUT_TEXT) {
|
|
return amduat_format_program_text(stream, program);
|
|
}
|
|
return amduat_format_program_json(stream, program);
|
|
}
|
|
|
|
static bool amduat_format_trace_text(FILE *stream,
|
|
const amduat_pel_trace_dag_value_t *trace,
|
|
amduat_format_ref_format_t ref_format) {
|
|
size_t i;
|
|
|
|
fprintf(stream, "pel1_version=%u\n", trace->pel1_version);
|
|
fprintf(stream, "scheme_ref=");
|
|
if (!amduat_format_ref_write_text(stream, trace->scheme_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
fprintf(stream, "program_ref=");
|
|
if (!amduat_format_ref_write_text(stream, trace->program_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
fprintf(stream, "status=%s(%u)\n",
|
|
amduat_format_pel_status_name(trace->status),
|
|
(unsigned int)trace->status);
|
|
fprintf(stream, "error_kind=%s(%u)\n",
|
|
amduat_format_pel_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_format_ref_write_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_format_ref_write_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_format_ref_write_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;
|
|
char prefix[64];
|
|
|
|
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_format_pel_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_format_ref_write_text(stream,
|
|
node->output_refs[j],
|
|
ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
}
|
|
fprintf(stream, "node_trace[%zu].diagnostics_len=%zu\n", i,
|
|
node->diagnostics_len);
|
|
snprintf(prefix, sizeof(prefix), "node_trace[%zu].", i);
|
|
if (!amduat_format_diagnostics_text(stream,
|
|
prefix,
|
|
node->diagnostics,
|
|
node->diagnostics_len)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool amduat_format_trace_json(FILE *stream,
|
|
const amduat_pel_trace_dag_value_t *trace,
|
|
amduat_format_ref_format_t ref_format) {
|
|
size_t i;
|
|
|
|
fputs("{\"pel1_version\":", stream);
|
|
fprintf(stream, "%u", trace->pel1_version);
|
|
fputs(",\"scheme_ref\":", stream);
|
|
if (!amduat_format_ref_write_json(stream, trace->scheme_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputs(",\"program_ref\":", stream);
|
|
if (!amduat_format_ref_write_json(stream, trace->program_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputs(",\"status\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_status_name(trace->status),
|
|
strlen(amduat_format_pel_status_name(trace->status))))) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"status_code\":%u",
|
|
(unsigned int)trace->summary.status_code);
|
|
fputs(",\"error_kind\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(
|
|
amduat_format_pel_error_kind_name(trace->summary.kind),
|
|
strlen(amduat_format_pel_error_kind_name(trace->summary.kind))))) {
|
|
return false;
|
|
}
|
|
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_format_ref_write_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_format_ref_write_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_format_ref_write_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);
|
|
if (!amduat_format_json_escape(stream, node->op_name)) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"version\":%u},", node->op_version);
|
|
fputs("\"status\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_node_status_name(node->status),
|
|
strlen(amduat_format_pel_node_status_name(
|
|
node->status))))) {
|
|
return false;
|
|
}
|
|
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_format_ref_write_json(stream,
|
|
node->output_refs[j],
|
|
ref_format)) {
|
|
return false;
|
|
}
|
|
}
|
|
fputs("],\"diagnostics\":", stream);
|
|
if (!amduat_format_diagnostics_json(stream,
|
|
node->diagnostics,
|
|
node->diagnostics_len)) {
|
|
return false;
|
|
}
|
|
fputs("}", stream);
|
|
}
|
|
fputs("]}", stream);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool amduat_format_pel_trace(FILE *stream,
|
|
const amduat_pel_trace_dag_value_t *trace,
|
|
amduat_format_output_t format,
|
|
amduat_format_ref_format_t ref_format) {
|
|
if (stream == NULL || trace == NULL) {
|
|
return false;
|
|
}
|
|
if (format == AMDUAT_FORMAT_OUTPUT_TEXT) {
|
|
return amduat_format_trace_text(stream, trace, ref_format);
|
|
}
|
|
return amduat_format_trace_json(stream, trace, ref_format);
|
|
}
|
|
|
|
static bool amduat_format_result_text(
|
|
FILE *stream,
|
|
const amduat_pel_surface_execution_result_t *result,
|
|
amduat_format_ref_format_t ref_format) {
|
|
size_t i;
|
|
|
|
fprintf(stream, "pel1_version=%u\n", result->pel1_version);
|
|
fprintf(stream, "scheme_ref=");
|
|
if (!amduat_format_ref_write_text(stream, result->scheme_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
fprintf(stream, "program_ref=");
|
|
if (!amduat_format_ref_write_text(stream, result->program_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
|
|
fprintf(stream, "status=%s(%u)\n",
|
|
amduat_format_pel_status_name(result->core_result.status),
|
|
(unsigned int)result->core_result.status);
|
|
fprintf(stream, "error_kind=%s(%u)\n",
|
|
amduat_format_pel_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_format_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_format_ref_write_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_format_ref_write_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_format_ref_write_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_format_ref_write_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_format_pel_store_phase_name(result->store_failure.phase),
|
|
(unsigned int)result->store_failure.phase);
|
|
fprintf(stream, "store_failure.error_code=%s(%u)\n",
|
|
amduat_format_pel_store_error_name(
|
|
result->store_failure.error_code),
|
|
(unsigned int)result->store_failure.error_code);
|
|
fprintf(stream, "store_failure.failing_ref=");
|
|
if (!amduat_format_ref_write_text(
|
|
stream, result->store_failure.failing_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputc('\n', stream);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool amduat_format_result_json(
|
|
FILE *stream,
|
|
const amduat_pel_surface_execution_result_t *result,
|
|
amduat_format_ref_format_t ref_format) {
|
|
size_t i;
|
|
|
|
fputs("{\"pel1_version\":", stream);
|
|
fprintf(stream, "%u", result->pel1_version);
|
|
fputs(",\"scheme_ref\":", stream);
|
|
if (!amduat_format_ref_write_json(stream, result->scheme_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputs(",\"program_ref\":", stream);
|
|
if (!amduat_format_ref_write_json(stream, result->program_ref, ref_format)) {
|
|
return false;
|
|
}
|
|
fputs(",\"status\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_status_name(
|
|
result->core_result.status),
|
|
strlen(amduat_format_pel_status_name(
|
|
result->core_result.status))))) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"status_code\":%u",
|
|
(unsigned int)result->core_result.summary.status_code);
|
|
fputs(",\"error_kind\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_error_kind_name(
|
|
result->core_result.summary.kind),
|
|
strlen(amduat_format_pel_error_kind_name(
|
|
result->core_result.summary.kind))))) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"error_kind_code\":%u",
|
|
(unsigned int)result->core_result.summary.kind);
|
|
fputs(",\"diagnostics\":", stream);
|
|
if (!amduat_format_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_format_ref_write_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_format_ref_write_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_format_ref_write_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_format_ref_write_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);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_store_phase_name(
|
|
result->store_failure.phase),
|
|
strlen(amduat_format_pel_store_phase_name(
|
|
result->store_failure.phase))))) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"phase_code\":%u",
|
|
(unsigned int)result->store_failure.phase);
|
|
fputs(",\"error_code\":", stream);
|
|
if (!amduat_format_json_escape(
|
|
stream,
|
|
amduat_octets(amduat_format_pel_store_error_name(
|
|
result->store_failure.error_code),
|
|
strlen(amduat_format_pel_store_error_name(
|
|
result->store_failure.error_code))))) {
|
|
return false;
|
|
}
|
|
fprintf(stream, ",\"error_code_id\":%u",
|
|
(unsigned int)result->store_failure.error_code);
|
|
fputs(",\"failing_ref\":", stream);
|
|
if (!amduat_format_ref_write_json(stream,
|
|
result->store_failure.failing_ref,
|
|
ref_format)) {
|
|
return false;
|
|
}
|
|
fputs("}", stream);
|
|
} else {
|
|
fputs("null", stream);
|
|
}
|
|
|
|
fputs("}", stream);
|
|
return true;
|
|
}
|
|
|
|
bool amduat_format_pel_result(FILE *stream,
|
|
const amduat_pel_surface_execution_result_t *result,
|
|
amduat_format_output_t format,
|
|
amduat_format_ref_format_t ref_format) {
|
|
if (stream == NULL || result == NULL) {
|
|
return false;
|
|
}
|
|
if (format == AMDUAT_FORMAT_OUTPUT_TEXT) {
|
|
return amduat_format_result_text(stream, result, ref_format);
|
|
}
|
|
return amduat_format_result_json(stream, result, ref_format);
|
|
}
|