Compare commits

...

23 Commits

Author SHA1 Message Date
90b5acd002 Ensure pack is initialised when loading an asset pack 2023-11-05 15:04:58 +00:00
e8fbe275f7 Move colour escape sequences closer to where they are used 2023-11-05 10:54:05 +00:00
ae61eef10a Ensure names are not mangled when used with C++ 2023-11-05 00:26:46 +00:00
fb1d1697f1 Build pakrd as shared object instead of static 2023-11-05 00:19:22 +00:00
2f3d8106ea Checkout cpath submodule 2023-11-04 14:26:37 +00:00
1f423b1d9b Fix warnings and errors reported by gcc 2023-11-04 14:22:20 +00:00
07a223f250 Switch to using gcc instead of clang 2023-11-04 14:21:44 +00:00
b2dc73148e Ensure mkdir doesn't fail if dist exists 2023-11-04 11:38:30 +00:00
1be318c239 Fix segfault when opening a pak that doesn't exist 2023-11-04 11:38:06 +00:00
7b472cac4b Update .gitignore 2023-11-04 11:16:59 +00:00
db4df86756 Rename pakrd.a to libpakrd.a 2023-11-04 11:16:51 +00:00
f8f08c7473 Update io.c to use cpath.h instead of path_utils.h 2023-11-03 22:58:38 +00:00
ca55dc2549 Update build script 2023-11-03 22:58:27 +00:00
ce4be85d14 Remove local copies of repo 2023-11-03 22:58:13 +00:00
3ec25758ef Add submodules 2023-11-03 22:57:19 +00:00
f3ae1aef64 Update .gitignore 2023-11-02 00:13:14 +00:00
c04e8bd4a3 Compile pakrd static library 2023-11-02 00:13:00 +00:00
c5c447d5c5 Complete pakrd_test implementation 2023-11-02 00:12:37 +00:00
490ccfc3c6 Add STRNEQ macro function 2023-11-02 00:12:23 +00:00
041167d26f Implement pack reading functions 2023-11-02 00:12:03 +00:00
7beac7e475 Add test utils 2023-11-02 00:11:44 +00:00
31d78bfcd3 Populate the toc_entries in asset_pack_t 2023-10-24 00:40:35 +01:00
07daa2ca19 Add debug config for pakrd_test 2023-10-24 00:40:21 +01:00
21 changed files with 262 additions and 182 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.cache
compile_commands.json
pckr
libpakrd.so
dist

8
.gitmodules vendored Normal file
View File

@@ -0,0 +1,8 @@
[submodule "intern/c-cpp-aliases"]
path = intern/c-cpp-aliases
url = https://git.thewizardapprentice.com/abdelrahman/c-cpp-aliases.git
branch = main
[submodule "intern/cpath"]
path = intern/cpath
url = https://git.thewizardapprentice.com/abdelrahman/cpath.git
branch = main

24
.vscode/launch.json vendored
View File

@@ -54,6 +54,30 @@
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Debug pakrd_test",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/pakrd_test",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

68
compile
View File

@@ -1,30 +1,10 @@
#!/bin/bash
#ESCAPE SEQUENCES
CLEAR="\033[0m"
BOLD="\033[1"
FG_BLACK="\033[30"
FG_RED="\033[31"
FG_GREEN="\033[32"
FG_YELLOW="\033[33"
FG_BLUE="\033[34"
FG_MAGENTA="\033[35"
FG_CYAN="\033[36"
FG_WHITE="\033[37"
FG_BR_BLACK="\033[90"
FG_BR_RED="\033[91"
FG_BR_GREEN="\033[92"
FG_BR_YELLOW="\033[93"
FG_BR_BLUE="\033[94"
FG_BR_MAGENTA="\033[95"
FG_BR_CYAN="\033[96"
FG_BR_WHITE="\033[97"
CC=clang
CFLAGS="-Wall -Werror -pedantic -Iinclude "
CC=gcc
CFLAGS="-Wall -Werror -pedantic -Iinclude -Iintern/c-cpp-aliases -Iintern/cpath/include "
PCKR_SRC="\
src/path_utils.c \
intern/cpath/src/cpath.c \
src/argparse.c \
src/io.c \
src/darr.c \
@@ -32,14 +12,21 @@ PCKR_SRC="\
src/pckr.c \
src/main.c"
PAKRD_SRC="\
intern/cpath/src/cpath.c \
src/io.c \
src/darr.c \
src/pak.c"
PAKRD_FLAGS="-fPIC -rdynamic -shared "
PCKR_TEST_SRC="\
src/path_utils.c \
intern/cpath/src/cpath.c \
src/io.c \
src/pckr_test.c"
PCKR_TEST_OUT="pckr_test"
PAKRD_TEST_SRC="\
src/path_utils.c \
intern/cpath/src/cpath.c \
src/io.c \
src/darr.c \
src/pak.c \
@@ -66,9 +53,13 @@ done
if [[ $BUILD_TYPE == "debug" ]]; then
CFLAGS+="-g "
PCKR_OUT="pckr"
PAKRD_OUT="libpakrd.so"
else
mkdir -p dist
cp ./include/pak.h dist
CFLAGS+="-O3 "
PCKR_OUT="../proj/pckr"
PCKR_OUT="dist/pckr"
PAKRD_OUT="dist/libpakrd.so"
fi
@@ -76,6 +67,10 @@ fi
(set -x ; $CC $CFLAGS $PCKR_SRC -o $PCKR_OUT)
# Build pakrd shared library
(set -x ; $CC $CFLAGS $PAKRD_FLAGS $PAKRD_SRC -o $PAKRD_OUT)
# Build pckr_test executable
(set -x ; $CC $CFLAGS $PCKR_TEST_SRC -o $PCKR_TEST_OUT)
@@ -88,6 +83,27 @@ fi
./pckr ./test_assets ./assets
#ESCAPE SEQUENCES
CLEAR="\033[0m"
BOLD="\033[1"
FG_BLACK="\033[30"
FG_RED="\033[31"
FG_GREEN="\033[32"
FG_YELLOW="\033[33"
FG_BLUE="\033[34"
FG_MAGENTA="\033[35"
FG_CYAN="\033[36"
FG_WHITE="\033[37"
FG_BR_BLACK="\033[90"
FG_BR_RED="\033[91"
FG_BR_GREEN="\033[92"
FG_BR_YELLOW="\033[93"
FG_BR_BLUE="\033[94"
FG_BR_MAGENTA="\033[95"
FG_BR_CYAN="\033[96"
FG_BR_WHITE="\033[97"
# Run pckr_test
(./$PCKR_TEST_OUT && echo -e "\npckr_test [${FG_BR_GREEN}m${BOLD}m SUCCESS $CLEAR]") || echo -e "\npckr_test [${FG_BR_RED}m${BOLD}m FAILURE $CLEAR]"

View File

@@ -1,27 +0,0 @@
#ifndef ALIASES_H
#define ALIASES_H
#include <stdint.h>
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
#define i8 int8_t
#define i16 int16_t
#define i32 int32_t
#define i64 int64_t
#define f32 float
#define f64 double
#define f128 long double
#define INTERNAL static
#define PERSISTENT static
#ifdef __cplusplus
#define CLASS_MEMBER static
#endif // __cplusplus
#endif // !ALIASES_H

View File

@@ -1,6 +1,10 @@
#ifndef ARGPARSE_H
#define ARGPARSE_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <linux/limits.h>
#include <stdbool.h>
@@ -17,4 +21,8 @@ typedef struct {
argparser_t parse_args(i32 argc, char *argv[]);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !ARGPARSE_H

View File

@@ -1,6 +1,10 @@
#ifndef D_ARR_H
#define D_ARR_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <stdbool.h>
@@ -13,4 +17,8 @@ i64 darr_add(darr_t **darr, void *item);
void **darr_get_items(darr_t *darr);
void darr_free(darr_t **darr);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !D_ARR_H

View File

@@ -1,12 +1,18 @@
#ifndef IO_H
#define IO_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define STREQ(S1, S2) (strcmp(S1, S2) == 0)
#define STRNEQ(S1, S2, COUNT) (strncmp(S1, S2, COUNT) == 0)
typedef struct dirwalk dirwalk_t;
typedef struct {
@@ -19,4 +25,8 @@ u64 get_file_length(FILE *fp);
void read_entire_file(void *dst, FILE *fp);
dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !IO_H

View File

@@ -1,12 +1,16 @@
#ifndef PAK_H
#define PAK_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <stdbool.h>
typedef struct {
u64 size;
u8 *data;
u8 data[];
} buf_t;
typedef struct {
@@ -41,7 +45,12 @@ typedef struct asset_pack asset_pack_t;
bool create_asset_pack(const char *dirpath, const char *output);
asset_pack_t *load_asset_pack(const char *filepath);
// buf_t read_file_from_pack(pak_read_t *pack, const char *filename);
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename);
void close_pack_file(buf_t **buf);
void close_asset_pack(asset_pack_t **pack);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !PAK_H

View File

@@ -1,18 +0,0 @@
#ifndef PATH_UTILS_H
#define PATH_UTILS_H
#include "aliases.h"
#define NUMPARTS(...) \
(sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
#define JOIN_PATH(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
void join_path(char *dst, u64 count, ...);
#define DIRNAME(DST, PATH) dirup(DST, 1, PATH)
#define DIRUP(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
void dirup(char *dst, u64 levels, const char *path);
#endif // !PATH_UTILS_H

View File

@@ -1,8 +1,16 @@
#ifndef PCKR_H
#define PCKR_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
i32 run_pckr(i32 argc, char *argv[]);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !PCKR_H

19
include/test_utils.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef TEST_UTILS_H
#define TEST_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define ARRLEN(ARR) (sizeof ARR / sizeof ARR[0])
typedef struct {
const char *name;
const char *contents;
} asset_t;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !TEST_UTILS_H

1
intern/c-cpp-aliases Submodule

Submodule intern/c-cpp-aliases added at f95f3aa499

1
intern/cpath Submodule

Submodule intern/cpath added at 076b1310e3

View File

@@ -7,10 +7,9 @@ argparser_t parse_args(i32 argc, char *argv[]) {
return (argparser_t){0};
}
argparser_t output = {
.succeeded = true,
.args = (pckr_args_t){0},
};
argparser_t output = {0};
output.succeeded = true;
output.args = (pckr_args_t){0};
realpath(argv[1], output.args.dir);
realpath(argv[2], output.args.output);

View File

@@ -40,7 +40,7 @@ i64 darr_add(darr_t **darr, void *item) {
return INVALID_IDX;
}
(*darr)->capacity = orig->capacity + BASE_CAPACITY;
(*darr)->capacity += BASE_CAPACITY;
}
u64 index = (*darr)->count;

View File

@@ -1,6 +1,6 @@
#include "io.h"
#include "aliases.h"
#include "path_utils.h"
#include "cpath.h"
#include <dirent.h>
#include <linux/limits.h>
#include <stdio.h>
@@ -16,8 +16,8 @@ struct dirwalk {
u64 count;
FILE *current_file;
DIR *current_dir;
char dst[PATH_MAX];
DIR *directories[MAX_DIR_DEPTH];
char dst[PATH_MAX + 1];
DIR *directories[MAX_DIR_DEPTH + 1];
};
u64 get_file_length(FILE *fp) {
@@ -73,7 +73,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
dirwalk_t *dw = *dirwalk;
char tmp[PATH_MAX] = {0};
char tmp[PATH_MAX + 1] = {0};
dirent_t *ep = NULL;
stat_t dirstat = {0};
@@ -102,7 +102,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
result.reading = true;
result.fp = dw->current_file;
strncpy(result.name, ep->d_name, NAME_MAX);
strncpy(result.name, ep->d_name, NAME_MAX + 1);
return result;
}
@@ -116,7 +116,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
if ((dirstat.st_mode & S_IFDIR) == S_IFDIR) {
memset(dw->dst, 0, length);
strncpy(dw->dst, tmp, length);
strncpy(dw->dst, tmp, length + 1);
dw->directories[(dw->count)++] = opendir(dw->dst);
@@ -128,7 +128,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
result.reading = true;
result.fp = dw->current_file;
strncpy(result.name, ep->d_name, NAME_MAX);
strncpy(result.name, ep->d_name, NAME_MAX + 1);
return result;
}
@@ -150,7 +150,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
u64 length = strlen(dw->dst);
strncpy(tmp, dw->dst, length);
strcpy(tmp, dw->dst);
memset(dw->dst, 0, length);

View File

@@ -34,13 +34,11 @@ void write_pak(const pak_t *pak, toc_entry_t **toc_entries,
bool create_asset_pack(const char *dirpath, const char *output) {
bool created = false;
char dst[PATH_MAX] = {0};
char dst[PATH_MAX + 1] = {0};
u64 output_length = strlen(output);
strncpy(dst, output, output_length);
strcpy(dst, output);
u64 ext_length = strlen(PAK_EXT);
strncat(dst, PAK_EXT, ext_length);
strcat(dst, PAK_EXT);
FILE *fp = fopen(dst, "wb");
if (!fp) {
@@ -130,9 +128,11 @@ asset_pack_t *load_asset_pack(const char *filepath) {
return NULL;
}
memset((void *)pack, 0, sizeof(asset_pack_t));
pack->fp = fopen(full_path, "rb");
if (!(pack->fp)) {
free(pack);
close_asset_pack(&pack);
return NULL;
}
@@ -145,16 +145,29 @@ asset_pack_t *load_asset_pack(const char *filepath) {
pack->toc = (u8 *)malloc(toc_size);
if (!(pack->toc)) {
fclose(pack->fp);
free(pack);
close_asset_pack(&pack);
return NULL;
}
fread((void *)(pack->toc), toc_size, 1, pack->fp);
// TODO (Abdelrahman): Populate the entries array
u64 entries_size = sizeof(toc_entry_t *) * pack->header.toc.count;
pack->toc_entries = (toc_entry_t **)malloc(entries_size);
if (!(pack->toc_entries)) {
close_asset_pack(&pack);
return NULL;
}
toc_entry_t *next = (toc_entry_t *)pack->toc;
for (u64 i = 0; i < pack->header.toc.count; ++i) {
pack->toc_entries[i] = next;
next = (toc_entry_t *)((u8 *)next + sizeof(toc_entry_t) + next->length);
}
pack->assets_offset = ftell(pack->fp);
@@ -163,18 +176,62 @@ asset_pack_t *load_asset_pack(const char *filepath) {
return pack;
}
// buf_t read_file_from_pack(pak_read_t *pack, const char *filename) {}
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename) {
toc_entry_t *entry = NULL;
buf_t *output = NULL;
for (u64 i = 0; i < pack->header.toc.count; ++i) {
entry = pack->toc_entries[i];
if (STRNEQ(filename, entry->name, entry->length)) {
fseek(pack->fp, pack->assets_offset + entry->offset, SEEK_SET);
u64 size = 0;
fread(&size, sizeof(u64), 1, pack->fp);
output = (buf_t *)malloc(sizeof(buf_t) + size);
if (!output) {
break;
}
output->size = size;
fread(&(output->data), size, 1, pack->fp);
break;
}
}
return output;
}
void close_pack_file(buf_t **buf) {
buf_t *b = *buf;
if (!b || b->size == 0) {
return;
}
free(*buf);
*buf = NULL;
}
void close_asset_pack(asset_pack_t **pack) {
if (!(*pack)) {
return;
}
if ((*pack)->toc_entries) {
free((*pack)->toc_entries);
}
if ((*pack)->toc) {
free((*pack)->toc);
}
fclose((*pack)->fp);
if ((*pack)->fp) {
fclose((*pack)->fp);
}
free(*pack);
@@ -195,7 +252,7 @@ toc_entry_t *create_toc_entry(const char *name, u64 offset) {
entry->offset = offset;
entry->length = length + 1;
strncpy(entry->name, name, length);
strcpy(entry->name, name);
return entry;
}

View File

@@ -1,4 +1,6 @@
#include "io.h"
#include "pak.h"
#include "test_utils.h"
#include <stdio.h>
#include <stdlib.h>
@@ -10,5 +12,40 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
asset_t assets[] = {
(asset_t){.name = "file01", .contents = "Hello\n"},
(asset_t){.name = "name.txt", .contents = "Abdelrahman\n"},
(asset_t){.name = "file02", .contents = "This is the second file\n"},
};
for (u64 i = 0; i < ARRLEN(assets); ++i) {
buf_t *buf = read_file_from_pack(pack, assets[i].name);
if (!buf || buf->size == 0) {
printf("Failed to read file %s\n", assets[i].name);
return EXIT_FAILURE;
}
if (!(STREQ((char *)(buf->data), assets[i].contents))) {
printf("File contents mismatch for file %s\n", assets[i].name);
return EXIT_FAILURE;
}
close_pack_file(&buf);
if (buf) {
printf("Failed to close file %s\n", assets[i].name);
return EXIT_FAILURE;
}
}
close_asset_pack(&pack);
if (pack) {
printf("Failed to close asset pack");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@@ -1,76 +0,0 @@
#include "path_utils.h"
#include "aliases.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(__unix__) || defined(__APPLE__) || defined(__ANDROID__)
INTERNAL char path_sep = '/';
#elif defined(_WIN32) || defined(_WIN64)
INTERNAL char path_sep = '\';
#endif
void join_root_and_leaf(const char *root, const char *leaf, char *dst);
void join_path(char *dst, u64 count, ...) {
va_list args;
va_start(args, count);
for (u64 i = 0; i < count; ++i) {
join_root_and_leaf(dst, va_arg(args, const char *), dst);
}
va_end(args);
}
void dirup(char *dst, u64 levels, const char *path) {
if (levels < 1) {
return;
}
u64 end_index = 0;
u64 sep_count = 0;
u64 length = strlen(path);
if (path[length - 1] == path_sep) {
--length;
}
for (u64 i = length - 1; i >= 0; --i) {
if (path[i] == path_sep) {
++sep_count;
end_index = i;
if (sep_count == levels) {
break;
}
}
}
if (sep_count < levels) {
end_index = 0;
}
strncpy(dst, path, end_index);
}
void join_root_and_leaf(const char *root, const char *leaf, char *dst) {
u64 root_length = strlen(root);
u64 root_end = root_length - 1;
u64 leaf_length = strlen(leaf);
u64 leaf_start = 0;
if (root[root_end] == path_sep) {
--root_end;
}
if (leaf[leaf_start] == path_sep) {
++leaf_start;
}
strncpy(dst, root, ++root_end);
dst[root_end] = path_sep;
strncpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start);
}

View File

@@ -1,19 +1,13 @@
#include "aliases.h"
#include "io.h"
#include "pak.h"
#include "test_utils.h"
#include <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRLEN(ARR) (sizeof ARR / sizeof ARR[0])
typedef struct {
const char *name;
const char *contents;
} asset_t;
i32 main(i32 argc, char *argv[]) {
char filepath[PATH_MAX] = {0};
realpath("assets.pak", filepath);