implements options

This commit is contained in:
SuperNovaa41 2025-02-07 12:23:19 -05:00
parent c6474c801b
commit f003e64412
3 changed files with 66 additions and 19 deletions

View File

@ -9,8 +9,9 @@ extern struct flags flags;
void init_flags(struct flags* flags) void init_flags(struct flags* flags)
{ {
flags->autoskip = false; flags->files[0] = NULL;
flags->binary = false; flags->files[1] = NULL;
flags->cols = 16; flags->cols = 16;
flags->octets = 2; flags->octets = 2;
flags->len = -1; // -1 means til EOF flags->len = -1; // -1 means til EOF
@ -51,6 +52,7 @@ void display_hex_chunk(hex_chunk_t* chunk, FILE* stream)
{ {
uint i, j; uint i, j;
bool newline; bool newline;
if (flags.decimaloffset) if (flags.decimaloffset)
fprintf(stream, "%08d", chunk->line * flags.cols); fprintf(stream, "%08d", chunk->line * flags.cols);
else else

View File

@ -19,8 +19,7 @@ typedef struct {
} hex_chunk_t; } hex_chunk_t;
struct flags { struct flags {
bool autoskip; // should we condense null lines into * char* files[2];
bool binary; // do binary dump instead of hex
uint cols; // choose the amount of columns to display (default 16) // done uint cols; // choose the amount of columns to display (default 16) // done
uint octets; // number of octets per line (default 2) // done uint octets; // number of octets per line (default 2) // done

View File

@ -2,10 +2,60 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <argp.h>
#include "include/hex.h" #include "include/hex.h"
#include "include/file.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 <cols> 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 <len> 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; struct flags flags;
int get_hex_lines(int len) int get_hex_lines(int len)
@ -29,25 +79,21 @@ int main(int argc, char* argv[])
init_flags(&flags); init_flags(&flags);
argp_parse(&argp, argc, argv, 0, 0, &flags);
if (argc < 2) { read_file_to_buf(flags.files[0], &file_content);
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);
filesize = (flags.len == -1) ? strlen(file_content) : flags.len; filesize = (flags.len == -1) ? strlen(file_content) : flags.len;
hex_lines = get_hex_lines(filesize); 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); hex_chunk_t* lines = malloc(sizeof(hex_chunk_t) * hex_lines);
for (i = 0; i < hex_lines; i++) { for (i = 0; i < hex_lines; i++) {