From f003e64412000cd7cb3e22796ab255272fbce51c Mon Sep 17 00:00:00 2001 From: SuperNovaa41 Date: Fri, 7 Feb 2025 12:23:19 -0500 Subject: [PATCH] implements options --- src/hex.c | 6 ++-- src/include/hex.h | 3 +- src/main.c | 76 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/hex.c b/src/hex.c index b2fddc4..c5d422b 100644 --- a/src/hex.c +++ b/src/hex.c @@ -9,8 +9,9 @@ extern struct flags flags; void init_flags(struct flags* flags) { - flags->autoskip = false; - flags->binary = false; + flags->files[0] = NULL; + flags->files[1] = NULL; + flags->cols = 16; flags->octets = 2; flags->len = -1; // -1 means til EOF @@ -51,6 +52,7 @@ void display_hex_chunk(hex_chunk_t* chunk, FILE* stream) { uint i, j; bool newline; + if (flags.decimaloffset) fprintf(stream, "%08d", chunk->line * flags.cols); else diff --git a/src/include/hex.h b/src/include/hex.h index d0ec815..d6a77ce 100644 --- a/src/include/hex.h +++ b/src/include/hex.h @@ -19,8 +19,7 @@ typedef struct { } hex_chunk_t; struct flags { - bool autoskip; // should we condense null lines into * - bool binary; // do binary dump instead of hex + char* files[2]; uint cols; // choose the amount of columns to display (default 16) // done uint octets; // number of octets per line (default 2) // done diff --git a/src/main.c b/src/main.c index c174f19..0982040 100644 --- a/src/main.c +++ b/src/main.c @@ -2,10 +2,60 @@ #include #include #include +#include #include "include/hex.h" #include "include/file.h" +const char* argp_program_version = "xxd 0.1"; +const char* argp_program_bug_address = "supernovaa41@gmx.com"; +static char doc[] = "Creates a hex dump of the given file."; +static char args_doc[] = "[INFILE] ([OUTFILE])"; +static struct argp_option options[] = { + {"cols", 'c', "cols", 0, "format octets per line. Default 16.", 0}, + {"octets", 'g', "bytes", 0, "number of octets per group in normal output. Default 2.", 0}, + {"len", 'l', "len", 0, "stop after octets.", 0}, + {"uppercase", 'u', 0, 0, "use upper case hex letters.", 0}, + {"decimaloffset", 'd', 0, 0, "show offset in decimal instead of hex.", 0}, + {0} +}; + +static error_t parse_opt(int key, char* arg, struct argp_state* state) +{ + struct flags* flags = state->input; + switch(key) { + case 'c': + flags->cols = atoi(arg); + break; + case 'g': + flags->octets = atoi(arg); + break; + case 'l': + flags->len = atoi(arg); + break; + case 'u': + flags->uppercase = true; + break; + case 'd': + flags->decimaloffset = true; + break; + case ARGP_KEY_ARG: + if (state->arg_num >= 2) + argp_usage(state); + flags->files[state->arg_num] = arg; + break; + case ARGP_KEY_END: + if (state->arg_num < 1) + argp_usage(state); + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0}; + struct flags flags; int get_hex_lines(int len) @@ -29,25 +79,21 @@ int main(int argc, char* argv[]) init_flags(&flags); + argp_parse(&argp, argc, argv, 0, 0, &flags); - if (argc < 2) { - fprintf(stderr, "Usage: %s [filename]\n", argv[0]); - return EXIT_FAILURE; - } - - stream = stdout; - outfile = false; - if (argc == 3) { - stream = fopen(argv[2], "w"); - outfile = true; - } - - read_file_to_buf(argv[1], &file_content); - + read_file_to_buf(flags.files[0], &file_content); filesize = (flags.len == -1) ? strlen(file_content) : flags.len; - hex_lines = get_hex_lines(filesize); + outfile = false; + if (flags.files[1] != NULL) { + stream = fopen(flags.files[1], "w"); + outfile = true; + } else { + stream = stdout; + } + + hex_chunk_t* lines = malloc(sizeof(hex_chunk_t) * hex_lines); for (i = 0; i < hex_lines; i++) {