summary refs log tree commit diff
path: root/src/util.c
blob: fc20e94481407eb7d9e75efd4477f21cec7ced73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h> // FILE *
#include <errno.h> // ESPIPE
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> // true/false

#include "util.h"

void *util_loadFile(FILE *const restrict file, size_t *const restrict outsize) { // open and fully load a file
	if (ftell(file) == -1L) {
		if (errno != ESPIPE) {
			// perror("ftell");
			return NULL;
		}
		fputs("opening pipes isnt supported yet\n", stderr);
		return NULL;
	} else {
		if (fseek(file, 0, SEEK_END)) {
			// perror("fseek");
		}
		long ssize = ftell(file);
		size_t size = (size_t) ssize;
		if (ssize == -1L) {
			// perror("ftell");
			return NULL;
		}
		rewind(file);
		void *buffer = malloc(size);
		if (buffer == NULL) {
			// perror("malloc");
			return NULL;
		}
		if (fread(buffer, 1, size, file) != size) {
			if (ferror(file)) {
				fputs("ferror set\n", stderr); // the internet was VERY helpful
			}
			// perror("fread");
			return NULL;
		}
		if (outsize != NULL) {
			*outsize = size;
		}
		return buffer;
	}
}

#if defined(__unix__) || defined(__APPLE__)
	#define DIR_SEPARATOR '/' // UNIX or OSX
#elif defined(_WIN32)
	#define DIR_SEPARATOR '\\' // DOS
#endif

char *util_executableRelativePath(char *path, char *execPath, size_t dirLength) { // allocated on the heap
	dirLength = 0;
	if (dirLength == 0) {
		for (dirLength = strlen(execPath); dirLength > 0 && execPath[dirLength - 1] != DIR_SEPARATOR; dirLength--)
			;
	}
	
	size_t fileLength = strlen(path);
	char *filePath = malloc(dirLength + fileLength + 1);
	filePath[dirLength + fileLength] = 0;
	memcpy(filePath, execPath, dirLength);
	memcpy(filePath + dirLength, path, fileLength);
	return filePath;
}