Skip to content

Commit

Permalink
Better path prefixes (#129)
Browse files Browse the repository at this point in the history
* Merge

* fix

* Merge

* Merge with main

* Fix windows compile

* Remove merge error

* Fix compilation

---------

Co-authored-by: Marek Maškarinec <[email protected]>
  • Loading branch information
skejeton and marekmaskarinec authored Jul 16, 2024
1 parent 397e6b1 commit 555f50a
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 43 deletions.
8 changes: 4 additions & 4 deletions main.um
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ fn init*() {
window::setViewport(th::Vf2{ 100, 100 })
var err: std::Err

loadedFont, err = font::load("etc/roboto.ttf", 16)
loadedFont, err = font::load("res://etc/roboto.ttf", 16)
std::exitif(err)

logo, err = image::load("etc/logo/logo-normal-white.png")
logo, err = image::load("res://etc/logo/logo-normal-white.png")
std::exitif(err)

fg = 0xadadd5ff
Expand All @@ -94,8 +94,8 @@ fn init*() {
"",
"PRESS ENTER TO",
"OPEN THE",
"HOMEPAGE" }

"HOMEPAGE"
}

window::onFrame.register(onFrame)
}
Expand Down
54 changes: 42 additions & 12 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,47 @@ extern int th_em_modulenames_count;
static char *
conv_path(char *path)
{
const char *RAW_PFX = "raw://";
const int RAW_PFX_LEN = strlen(RAW_PFX);

if (strncmp(path, RAW_PFX, RAW_PFX_LEN) == 0) {
char *out = malloc(strlen(path) - RAW_PFX_LEN + 1);
out[strlen(path) - RAW_PFX_LEN] = 0;
strcpy(out, path + RAW_PFX_LEN);
return out;
enum prefix
{
PFX_RAW,
PFX_RES,
PFX_DATA,
};

const char *prefixes[] = {
[PFX_RAW] = "raw://",
[PFX_RES] = "res://",
[PFX_DATA] = "data://",
};

const ssize_t path_len = strlen(path);
enum prefix pfx = PFX_RAW;

for (int i = 0; i < sizeof(prefixes) / sizeof(prefixes[0]); ++i) {
const ssize_t prefix_len = strlen(prefixes[i]);
if (path_len >= prefix_len && memcmp(path, prefixes[i], prefix_len) == 0) {
pfx = i;
path += prefix_len;
break;
}
}

char *out = NULL;

switch (pfx) {
case PFX_RAW: out = strdup(path); break;
case PFX_RES:
out = calloc(1, strlen(thg->res_dir) + strlen(path) + 1);
strcpy(out, thg->res_dir);
strcat(out, path);
break;
case PFX_DATA:
out = calloc(1, strlen(thg->data_dir) + strlen(path) + 1);
strcpy(out, thg->data_dir);
strcat(out, path);
break;
}

size_t len = strlen(thg->respath) + strlen(path);
char *out = malloc(len + 1);
out[len] = 0;
sprintf(out, "%s%s", thg->respath, path);
return out;
}

Expand All @@ -48,6 +75,8 @@ umth_fopen(UmkaStackSlot *p, UmkaStackSlot *r)
char *name = (char *)umkaGetParam(p, 0)->ptrVal;
const char *mode = (const char *)umkaGetParam(p, 1)->ptrVal;

printf("fopen\n");

char *path = conv_path(name);
FILE *f = fopen(path, mode);
free(path);
Expand Down Expand Up @@ -1433,6 +1462,7 @@ _th_umka_bind(void *umka)
{
// etc
umkaAddFunc(umka, "umth_fopen", &umth_fopen);
umkaAddFunc(umka, "rtlfopen", &umth_fopen);
umkaAddFunc(umka, "umth_th_getglobal", &umth_th_getglobal);
umkaAddFunc(umka, "umth_th_getfuncs", &umth_th_getfuncs);

Expand Down
89 changes: 63 additions & 26 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#define __USE_MINGW_ANSI_STDIO 1

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bindings.h"
Expand All @@ -12,9 +15,10 @@
#include <umprof.h>
#ifdef _WIN32
#include <windows.h>
#include <sys/stat.h>
#include <sys/types.h>
#define mkdir(p, m) mkdir(p)
#else
#include <sys/wait.h>
#include <unistd.h>
#endif
#include <sokol_app.h>

Expand All @@ -23,6 +27,8 @@
#define TH_GITVER ""
#endif

#define PATH_MAX 512

th_global *thg;

extern char *th_em_modulenames[];
Expand All @@ -41,6 +47,57 @@ warning(UmkaError *error)
int
th_init(const char *scriptpath, const char *script_src)
{
{
thg->res_dir = strdup(scriptpath);
char *fname = strrchr(thg->res_dir, '/');
ssize_t len = fname == NULL ? strlen(thg->res_dir) : strlen(fname) - 1;
thg->res_dir[strlen(thg->res_dir) - len] = '\0';
}

{
char *res_dir = thg->res_dir[0] == '\0' ? "./" : thg->res_dir;
#ifdef _WIN32
char abs[PATH_MAX];
GetFullPathNameA(res_dir, PATH_MAX - 1, abs, NULL);
#else
char *abs = realpath(res_dir, NULL);
#endif
char *dirname = strrchr(abs, '/');
ssize_t dirlen = dirname == NULL ? 0 : strlen(dirname);

bool data_path_allocd = 0;
#ifdef _WIN32
char *data_path = getenv("APPDATA");
#else
char *data_path = getenv("XDG_DATA_HOME");
if (data_path == NULL) {
data_path = getenv("HOME");
if (data_path == NULL) {
th_error("Could not find home directory");
}
data_path_allocd = 1;
char *tmp = calloc(1, strlen(data_path) + strlen("/.local/share") + 1);
sprintf(tmp, "%s/.local/share", data_path);
data_path = tmp;
}
#endif

thg->data_dir = calloc(1, strlen(data_path) + strlen("/tophat") + dirlen + 1);
strcpy(thg->data_dir, data_path);

strcat(thg->data_dir, "/tophat");
mkdir(thg->data_dir, 0777);

strcat(thg->data_dir, dirname == NULL ? "" : dirname);
mkdir(thg->data_dir, 0777);

if (data_path_allocd)
free(data_path);
#ifndef _WIN32
free(abs);
#endif
}

char *mainmod_fmt = "import (mainmod = \"%s\"; \"window.um\")\n"
"fn __th_init*() {\n"
" _ := window::w\n"
Expand Down Expand Up @@ -143,6 +200,9 @@ th_deinit()
th_font_deinit();
th_image_deinit();

free(thg->res_dir);
free(thg->data_dir);

free(thg);
thg = NULL;
}
Expand Down Expand Up @@ -196,9 +256,6 @@ th_main(int argc, char *argv[])
thg->argc = argc;
thg->argv = argv;

const char *respath = "";

thg->respath[0] = 0;
const char *scriptpath = "main.um";

thg->argOffset = 1;
Expand Down Expand Up @@ -281,14 +338,6 @@ th_main(int argc, char *argv[])
"\n%s\n",
umkaGetVersion());
exit(0);
} else if (strcmp(argv[thg->argOffset], "-dir") == 0) {
if ((argc - thg->argOffset) < 2) {
th_error("dir takes 1 argument.\n");
exit(1);
}

respath = argv[thg->argOffset + 1];
thg->argOffset += 2;
} else if (strcmp(argv[thg->argOffset], "-help") == 0) {
th_info("tophat - a minimalist game engine for making games in umka.\n"
"Just launching tophat without flags will run main.um\n"
Expand All @@ -300,7 +349,7 @@ th_main(int argc, char *argv[])
" -dpiaware - enable DPI awareness\n"
" -help - show this help\n"
" -license - print the license\n"
" -main - specify the main file (dir/main.um by default)\n"
" -main - specify the main file (./main.um by default)\n"
" -modsrc <module name> - print source of a builtin module\n"
" -prof - use the profiler\n"
" -profjson - output profiler stuff as Google JSON profile\n"
Expand All @@ -321,18 +370,6 @@ th_main(int argc, char *argv[])

char regularizedScriptPath[BUFSIZ];
th_regularize_path(scriptpath, "./", regularizedScriptPath, sizeof regularizedScriptPath);
th_regularize_path(respath, "./", thg->respath, sizeof thg->respath);

size_t respath_len = strlen(thg->respath);

if (respath_len > 0 && thg->respath[respath_len - 1] != '/' && thg->respath[0] != 0) {
if (respath_len == sizeof(thg->respath) - 1) {
th_error("Respath is too long");
return 1;
}

strncat(thg->respath, "/", sizeof(thg->respath) - 1);
}

FILE *f;
if ((f = fopen(regularizedScriptPath, "r"))) {
Expand Down
11 changes: 10 additions & 1 deletion src/tophat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
#include <stdint.h>
#include <umka_api.h>

#if _WIN32 || _WIN64
#if _WIN64
typedef int64_t ssize_t;
#else
typedef int32_t ssize_t;
#endif
#endif

#define PI 3.1415926535897932

#define INPUT_STRING_SIZE 256
Expand Down Expand Up @@ -276,7 +284,8 @@ typedef struct
// struct holding all tophat's global variables.
typedef struct
{
char respath[4096];
char *res_dir;
char *data_dir;
fu scaling;
th_vf2 offset;
th_vf2 viewport;
Expand Down

0 comments on commit 555f50a

Please sign in to comment.