commit f80b25599bfec345e19b98deeb48d824495d8589 Author: SuperNovaa41 Date: Thu Feb 6 13:48:20 2025 -0500 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bde8c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +*.o diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..a61f41f --- /dev/null +++ b/src/Makefile @@ -0,0 +1,16 @@ +TARGET=xxd +CC=gcc + +OBJ = main.o hex.o + +$(TARGET): $(OBJ) + mkdir -p ../build + $(CC) -Wall -g -o $(TARGET) $(OBJ) -g + mv $(TARGET) ../build/ + +main.o: include/hex.h +hex.o: include/hex.h + +.PHONY: clean +clean: + rm -rf ../build $(OBJ) diff --git a/src/hex.c b/src/hex.c new file mode 100644 index 0000000..b9438ae --- /dev/null +++ b/src/hex.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +#include "include/hex.h" + +void free_hex_chunk(hex_chunk_t* chunk) +{ + free(chunk->text); + free(chunk->hex); +} + +void add_text_to_chunk(char* src, char** dst) +{ + *dst = malloc(sizeof(char) * (TEXT_LINE_LEN + 1)); + + strncpy(*dst, src, 16); + (*dst)[TEXT_LINE_LEN] = '\0'; +} + +void convert_text_to_hex(hex_chunk_t* chunk) +{ + int i, j; + chunk->hex = malloc(sizeof(char) * (HEX_LINE_LEN + 1)); + + for (i = 0, j = 0; i < HEX_LINE_LEN; i += 2, j += 1) { + if (chunk->text[j] == '\0') + snprintf(chunk->hex + i, 3, " "); + else + snprintf(chunk->hex + i, 3, "%02x", chunk->text[j]); + } +} + +// TODO: clean up the text formatting to not print it every time +void display_hex_chunk(hex_chunk_t* chunk) +{ + int i, j; + + printf("%08x: ", chunk->line * 16); + for (i = 0; i < HEX_LINE_LEN; i += 4) { + for (j = 0; j < 4; j += 2) { + if (((chunk->hex + i) + j)[0] == '0' && ((chunk->hex + i) + j)[1] == 'a') + printf("\x1b[33m"); + else + printf("\x1b[32m"); + printf("%2.2s", chunk->hex + i + j); + } + printf(" "); + } + + for (i = 0; i < TEXT_LINE_LEN; i++) { + if (chunk->text[i] == '\n' || chunk->text[i] == EOF) + printf("\x1b[33m."); + else + printf("\x1b[32m%c", chunk->text[i]); + } + puts("\x1b[0m"); +} diff --git a/src/include/hex.h b/src/include/hex.h new file mode 100644 index 0000000..a5f1a12 --- /dev/null +++ b/src/include/hex.h @@ -0,0 +1,18 @@ +#ifndef HEX_H +#define HEX_H + +#define TEXT_LINE_LEN 16 +#define HEX_LINE_LEN 32 + +typedef struct { + int line; + char* text; + char* hex; +} hex_chunk_t; + +void free_hex_chunk(hex_chunk_t* chunk); +void add_text_to_chunk(char* src, char** dst); +void convert_text_to_hex(hex_chunk_t* chunk); +void display_hex_chunk(hex_chunk_t* chunk); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..178e564 --- /dev/null +++ b/src/main.c @@ -0,0 +1,105 @@ +#include +#include +#include + +#include "include/hex.h" + +/** + * read_file_to_buf + * + * - const char* filename - Name of the file we're opening + * - char** buf - pointer to the buffer to hold the file in + * + * read the file into a buffer to prevent unnecessary file ops + */ +void read_file_to_buf(const char* filename, char** buf) +{ + FILE* f; + int err, bufsize, newlen; + + f = fopen(filename, "r"); + if (f == NULL) { + perror("fopen"); + exit(EXIT_FAILURE); + } + + err = fseek(f, 0L, SEEK_END); + if (err != 0) { + perror("fseek"); + fclose(f); + exit(EXIT_FAILURE); } + + bufsize = ftell(f); + if (bufsize == -1) { + perror("ftell"); + fclose(f); + exit(EXIT_FAILURE); + } + + (*buf) = malloc(sizeof(char) * (bufsize + 1)); + if (*buf == NULL) { + perror("malloc"); + fclose(f); + exit(EXIT_FAILURE); + } + + rewind(f); + + newlen = fread(*buf, sizeof(char), bufsize, f); + if (ferror(f) != 0) { + perror("fread"); + fclose(f); + exit(EXIT_FAILURE); + } else { + (*buf)[newlen++] = '\0'; // just to be safe + } + + fclose(f); +} + +int get_hex_lines(int len) +{ + int out; + + out = len / 16; + if (len % 16 != 0) + out++; + + return out; +} + +int main(int argc, char* argv[]) +{ + char* file_content; + int hex_lines, i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s [filename]\n", argv[0]); + return EXIT_FAILURE; + } + + read_file_to_buf(argv[1], &file_content); + hex_lines = get_hex_lines(strlen(file_content)); + + hex_chunk_t* lines = malloc(sizeof(hex_chunk_t) * hex_lines); + + for (i = 0; i < hex_lines; i++) { + lines[i].line = i; + + add_text_to_chunk(file_content + (i * 16), &(lines[i].text)); + convert_text_to_hex(&lines[i]); + } + + for (i = 0; i < hex_lines; i++) + display_hex_chunk(&(lines[i])); + + + + free(file_content); + for (i = 0; i < hex_lines; i++) + free_hex_chunk(&(lines[i])); + free(lines); + + + return 0; +}