init commit

This commit is contained in:
SuperNovaa41 2025-02-06 13:48:20 -05:00
commit f80b25599b
5 changed files with 200 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/
*.o

16
src/Makefile Normal file
View File

@ -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)

59
src/hex.c Normal file
View File

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#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");
}

18
src/include/hex.h Normal file
View File

@ -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

105
src/main.c Normal file
View File

@ -0,0 +1,105 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}