Fix minor generation bug, reformat CLI parsing.
diff --git a/cli-app/cper-convert.c b/cli-app/cper-convert.c
index d1db4d2..26194b7 100644
--- a/cli-app/cper-convert.c
+++ b/cli-app/cper-convert.c
@@ -13,29 +13,61 @@
#include "../cper-parse.h"
#include "../json-schema.h"
-void cper_to_json(int argc, char *argv[]);
-void json_to_cper(int argc, char *argv[]);
+void cper_to_json(char *in_file, char *out_file);
+void json_to_cper(char *in_file, char *out_file, char *specification_file,
+ char *program_dir, int no_validate, int debug);
void print_help(void);
int main(int argc, char *argv[])
{
- //Ensure at least one argument is present.
- if (argc < 2) {
+ //Print help if requested.
+ if (argc == 2 && strcmp(argv[1], "--help") == 0) {
+ print_help();
+ return 0;
+ }
+
+ //Ensure at least two arguments are present.
+ if (argc < 3) {
printf("Invalid number of arguments. See 'cper-convert --help' for command information.\n");
return -1;
}
//Parse the command line arguments.
- char* input_file = NULL;
- char* output_file = NULL;
+ char *input_file = argv[2];
+ char *output_file = NULL;
+ char *specification_file = NULL;
+ int no_validate = 0;
+ int debug = 0;
+ for (int i = 3; i < argc; i++) {
+ if (strcmp(argv[i], "--out") == 0 && i < argc - 1) {
+ //Output file.
+ output_file = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--specification") == 0 &&
+ i < argc - 1) {
+ //Specification file.
+ specification_file = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--no-validate") == 0) {
+ //No validation to be used.
+ //Invalidates specification file.
+ specification_file = NULL;
+ no_validate = 1;
+ } else if (strcmp(argv[i], "--debug") == 0) {
+ //Debug output on.
+ debug = 1;
+ } else {
+ printf("Unrecognised argument '%s'. See 'cper-convert --help' for command information.\n",
+ argv[i]);
+ }
+ }
//Run the requested command.
if (strcmp(argv[1], "to-json") == 0)
- cper_to_json(argc, argv);
+ cper_to_json(input_file, output_file);
else if (strcmp(argv[1], "to-cper") == 0)
- json_to_cper(argc, argv);
- else if (strcmp(argv[1], "--help") == 0)
- print_help();
+ json_to_cper(input_file, output_file, specification_file,
+ argv[0], no_validate, debug);
else {
printf("Unrecognised argument '%s'. See 'cper-convert --help' for command information.\n",
argv[1]);
@@ -46,18 +78,13 @@
}
//Command for converting a provided CPER log file into JSON.
-void cper_to_json(int argc, char *argv[])
+void cper_to_json(char *in_file, char *out_file)
{
- if (argc < 3) {
- printf("Insufficient number of arguments for 'to-json'. See 'cper-convert --help' for command information.\n");
- return;
- }
-
//Get a handle for the log file.
- FILE *cper_file = fopen(argv[2], "r");
+ FILE *cper_file = fopen(in_file, "r");
if (cper_file == NULL) {
printf("Could not open provided CPER file '%s', file handle returned null.\n",
- argv[2]);
+ in_file);
return;
}
@@ -69,23 +96,16 @@
//Check whether there is a "--out" argument, if there is, then output to file instead.
//Otherwise, just send to console.
- if (argc != 5) {
+ if (out_file == NULL) {
printf("%s\n", json_output);
return;
}
- //File out argument exists. Argument valid?
- if (strcmp(argv[3], "--out") != 0) {
- printf("Invalid argument '%s' for command 'to-json'. See 'cper-convert --help' for command information.\n",
- argv[3]);
- return;
- }
-
//Try to open a file handle to the desired output file.
- FILE *json_file = fopen(argv[4], "w");
+ FILE *json_file = fopen(out_file, "w");
if (json_file == NULL) {
printf("Could not get a handle for output file '%s', file handle returned null.\n",
- argv[4]);
+ out_file);
return;
}
@@ -95,63 +115,51 @@
}
//Command for converting a provided CPER-JSON JSON file to CPER binary.
-void json_to_cper(int argc, char *argv[])
+void json_to_cper(char *in_file, char *out_file, char *specification_file,
+ char *program_dir, int no_validate, int debug)
{
- if (argc < 5) {
- printf("Insufficient number of arguments for 'to-cper'. See 'cper-convert --help' for command information.\n");
+ //Verify output file exists.
+ if (out_file == NULL) {
+ printf("No output file provided for 'to-cper'. See 'cper-convert --help' for command information.\n");
return;
}
//Read JSON IR from file.
- json_object *ir = json_object_from_file(argv[2]);
+ json_object *ir = json_object_from_file(in_file);
if (ir == NULL) {
printf("Could not read JSON from file '%s', import returned null.\n",
- argv[2]);
+ in_file);
return;
}
- //Are we skipping validation?
- int do_validate = 1;
- if (argc >= 6 && argc < 8) {
- if (strcmp(argv[5], "--no-validate") == 0) {
- do_validate = 0;
- }
- }
-
//Validate the JSON against specification, unless otherwise specified.
- if (do_validate) {
- char *specification_path = NULL;
+ if (!no_validate) {
+ int using_default_spec_path = 0;
//Is there a specification file path?
- if (argc >= 7 &&
- strcmp(argv[argc - 2], "--specification") == 0) {
- specification_path = argv[argc - 1];
- } else {
+ if (specification_file == NULL) {
+ using_default_spec_path = 1;
+
//Make the specification path the assumed default (application directory + specification/cper-json.json).
- specification_path = malloc(PATH_MAX);
- char *dir = dirname(argv[0]);
- strcpy(specification_path, dir);
- strcat(specification_path,
+ specification_file = malloc(PATH_MAX);
+ char *dir = dirname(program_dir);
+ strcpy(specification_file, dir);
+ strcat(specification_file,
"/specification/cper-json.json");
}
//Enable debug mode if indicated.
- for (int i = 5; i < argc; i++) {
- if (strcmp(argv[i], "--debug") == 0) {
- validate_schema_debug_enable();
- printf("debug enabled.\n");
- break;
- }
- }
+ if (debug)
+ validate_schema_debug_enable();
//Attempt to verify with the the specification.
char *error_message = malloc(JSON_ERROR_MSG_MAX_LEN);
- int success = validate_schema_from_file(specification_path, ir,
+ int success = validate_schema_from_file(specification_file, ir,
error_message);
//Free specification path (if necessary).
- if (argc == 5)
- free(specification_path);
+ if (using_default_spec_path)
+ free(specification_file);
//If failed, early exit before conversion.
if (!success) {
@@ -165,10 +173,10 @@
//Attempt a conversion.
//Open a read for the output file.
- FILE *cper_file = fopen(argv[4], "w");
+ FILE *cper_file = fopen(out_file, "w");
if (cper_file == NULL) {
printf("Could not open output file '%s', file handle returned null.\n",
- argv[4]);
+ out_file);
return;
}
@@ -181,7 +189,7 @@
void print_help(void)
{
printf(":: to-json cper.file [--out file.name]\n");
- printf("\tConverts the provided CPER log file into JSON, by default outputting to console. If '--out' is specified,\n");
+ printf("\tConverts the provided CPER log file into JSON, by default writing to stdout. If '--out' is specified,\n");
printf("\tThe outputted JSON will be written to the provided file name instead.\n");
printf("\n:: to-cper cper.json --out file.name [--no-validate] [--debug] [--specification some/spec/path.json]\n");
printf("\tConverts the provided CPER-JSON JSON file into CPER binary. An output file must be specified with '--out'.\n");
@@ -189,6 +197,7 @@
printf("\tis provided with '--specification', then it will default to 'argv[0] + /specification/cper-json.json'.\n");
printf("\tIf the '--no-validate' argument is set, then the provided JSON will not be validated. Be warned, this may cause\n");
printf("\tpremature exit/unexpected behaviour in CPER output.\n");
+ printf("\tIf '--debug' is set, then debug output for JSON specification parsing will be printed to stdout.\n");
printf("\n:: --help\n");
printf("\tDisplays help information to the console.\n");
}
\ No newline at end of file
diff --git a/generator/cper-generate-cli.c b/generator/cper-generate-cli.c
index 5d9c01e..0f0399b 100644
--- a/generator/cper-generate-cli.c
+++ b/generator/cper-generate-cli.c
@@ -5,6 +5,7 @@
**/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "../edk/Cper.h"
#include "cper-generate.h"
@@ -19,24 +20,51 @@
return 0;
}
- //Ensure the minimum number of arguments.
- if (argc < 5) {
- printf("Insufficient number of arguments. See 'cper-generate --help' for command information.\n");
+ //Parse the command line arguments.
+ char *out_file = NULL;
+ char **sections = NULL;
+ UINT16 num_sections = 0;
+ for (int i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--out") == 0 && i < argc - 1) {
+ out_file = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--sections") == 0 && i < argc - 1) {
+ //All arguments after this must be section names.
+ num_sections = argc - i - 1;
+ sections = malloc(sizeof(char *) * num_sections);
+ i++;
+
+ for (int j = i; j < argc; j++)
+ sections[j - i] = argv[j];
+ break;
+ } else {
+ printf("Unrecognised argument '%s'. For command information, refer to 'cper-generate --help'.\n",
+ argv[i]);
+ return -1;
+ }
+ }
+
+ //If no output file passed as argument, exit.
+ if (out_file == NULL) {
+ printf("No output file provided. For command information, refer to 'cper-generate --help'.\n");
return -1;
}
//Open a file handle to write output.
- FILE *cper_file = fopen(argv[2], "w");
+ FILE *cper_file = fopen(out_file, "w");
if (cper_file == NULL) {
printf("Could not get a handle for output file '%s', file handle returned null.\n",
- argv[2]);
+ out_file);
return -1;
}
//Generate the record. Type names start from argv[4].
- UINT16 num_sections = argc - 4;
- generate_cper_record(argv + 4, num_sections, cper_file);
+ generate_cper_record(sections, num_sections, cper_file);
+
+ //Close & free remaining resources.
fclose(cper_file);
+ if (sections != NULL)
+ free(sections);
}
//Prints command help for this CPER generator.
diff --git a/generator/sections/gen-section-cxl-protocol.c b/generator/sections/gen-section-cxl-protocol.c
index e0570b4..3ff6fbb 100644
--- a/generator/sections/gen-section-cxl-protocol.c
+++ b/generator/sections/gen-section-cxl-protocol.c
@@ -36,7 +36,7 @@
if (cxl_agent_type == 0)
{
for (int i=0; i<3; i++)
- *(bytes + 20 + i) = 0; //CXL agent address bytes 5-7.
+ *(bytes + 21 + i) = 0; //CXL agent address bytes 5-7.
}
*(bytes + 34) &= ~0b111; //Device ID byte 10 bits 0-2.
diff --git a/generator/sections/gen-section-pci-bus.c b/generator/sections/gen-section-pci-bus.c
index 406a27e..dc2381d 100644
--- a/generator/sections/gen-section-pci-bus.c
+++ b/generator/sections/gen-section-pci-bus.c
@@ -23,7 +23,7 @@
UINT32* reserved = (UINT32*)(bytes + 20);
*reserved = 0;
UINT64* bus_command = (UINT64*)(bytes + 40);
- *bus_command &= (0b1 << 56); //Bus command bytes bar bit 56.
+ *bus_command &= ((UINT64)0b1 << 56); //Bus command bytes bar bit 56.
//Fix values that could be above range.
UINT16* error_type = (UINT16*)(bytes + 16);