Blame src/common.c

8535a3
28a314
#include <dirent.h></dirent.h>
28a314
#include <sys stat.h=""></sys>
28a314
8535a3
#include "private.h"
8535a3
8535a3
8eb855
int heliInitialized;
8eb855
HeliArray heliObjectsSet;
8535a3
8535a3
1015c5
struct _Directory {
1015c5
	HeliArray files;
1015c5
};
1015c5
1015c5
59dae5
static char *colors[][2] = {
59dae5
	{ "transparent", "0 0 0 0" },
09c823
	
59dae5
	{ "black",       "0 0 0 1" },
59dae5
	{ "white",       "1 1 1 1" },
59dae5
	{ "gray",        "0.5 0.5 0.5 1" },
09c823
	
59dae5
	{ "red",         "1 0 0 1" },
59dae5
	{ "green",       "0 1 0 1" },
59dae5
	{ "blue",        "0 0 1 1" },
09c823
	
59dae5
	{ "yellow",      "1 1 0 1" },
59dae5
	{ "magenta",     "1 0 1 1" },
59dae5
	{ "cyan",        "0 1 1 1" },
59dae5
	
59dae5
	{ "brown",       "0.5 0.5 0 1" },
09c823
};
09c823
09c823
8535a3
int randomNumber(int min, int max)
8535a3
	{ return max <= min ? min : rand()%(max - min + 1) + min; }
8535a3
8535a3
double randomFloat()
8535a3
	{ return (double)rand()/(double)RAND_MAX; }
8535a3
8535a3
1015c5
Directory openDirectory(const char *path) {
8eb855
	if (!heliInitialized) return NULL;
28a314
	
28a314
	DIR *dir = opendir(path);
1015c5
	if (!dir) return NULL;
1015c5
	
87fe10
	Directory d = calloc(1, sizeof(*d));
28a314
	
28a314
	struct dirent *ent;
28a314
	while((ent = readdir(dir)) != NULL) {
87fe10
		if ( !ent->d_name[0]
87fe10
		  || strcmp(ent->d_name, ".") == 0
87fe10
		  || strcmp(ent->d_name, "..") == 0 ) continue;
28a314
		heliStringmapAdd(&d->files, ent->d_name, NULL, NULL);
1015c5
	}
28a314
	closedir(dir);
1015c5
	
8eb855
	heliObjectRegister(d, (HeliFreeCallback)&closeDirectory);
1015c5
	return d;
1015c5
}
1015c5
1015c5
void closeDirectory(Directory directory) {
1015c5
	if (!directory) return;
8eb855
	heliObjectUnregister(directory);
1015c5
	heliArrayDestroy(&directory->files);
1015c5
	free(directory);
1015c5
}
1015c5
1015c5
int directoryGetCount(Directory directory)
1015c5
	{ return directory->files.count; }
1015c5
1015c5
const char* directoryGet(Directory directory, int i)
1015c5
	{ return (const char*)heliArrayGetKey(&directory->files, i); }
1015c5
1015c5
28a314
int fileExists(const char *path) {
28a314
	struct stat s = {};
28a314
	return stat(path, &s) == 0 && !(s.st_mode & S_IFDIR);
28a314
}
28a314
28a314
int directoryExists(const char *path) {
28a314
	struct stat s = {};
28a314
	return stat(path, &s) == 0 && (s.st_mode & S_IFDIR);
28a314
}
1015c5
1015c5
8535a3
char* heliStringCopy(const char *x) {
8535a3
	int len = strlen(x) + 1;
f63775
	char *cp = malloc(len);
8535a3
	memcpy(cp, x, len);
8535a3
	return cp;
8535a3
}
8535a3
dba3fc
char* heliStringConcat(const char *a, const char *b) {
dba3fc
	int la = strlen(a);
dba3fc
	int lb = strlen(b);
dba3fc
	char *s = malloc(la + lb + 1);
dba3fc
	memcpy(s, a, la);
dba3fc
	memcpy(s + la, b, lb);
dba3fc
	s[la + lb] = 0;
dba3fc
	return s;
dba3fc
}
dba3fc
8535a3
char* heliStringConcat3(const char *a, const char *b, const char *c) {
8535a3
	int la = strlen(a);
8535a3
	int lb = strlen(b);
8535a3
	int lc = strlen(c);
8535a3
	char *s = malloc(la + lb + lc + 1);
8535a3
	memcpy(s, a, la);
8535a3
	memcpy(s + la, b, lb);
8535a3
	memcpy(s + la + lb, c, lc);
8535a3
	s[la + lb + lc] = 0;
8535a3
	return s;
8535a3
}
8535a3
8535a3
int heliStringEndsWithLowcase(const char *s, const char *tail) {
8535a3
	int ls = strlen(s);
8535a3
	int lt = strlen(tail);
8535a3
	if (lt > ls) return FALSE;
8535a3
	for(int i = 0; i < lt; ++i)
8535a3
		if (tolower(s[ls - i]) != tolower(tail[lt - i]))
8535a3
			return FALSE;
8535a3
	return TRUE;
8535a3
}
8535a3
8535a3
void heliLowercase(char *x)
981405
	{ while(*x) { *x = tolower(*x); ++x; } }
8535a3
09c823
d4e89f
static unsigned int colorToInt(double c) {
d4e89f
	if (!(c > 0)) c = 0;
d4e89f
	if (!(c < 1)) c = 1;
d4e89f
	return (unsigned int)floor(c*255.99);
d4e89f
}
d4e89f
d4e89f
d4e89f
void heliColorToDouble(unsigned int code, double *rgba) {
d4e89f
	rgba[0] = ( code >> 24         )/255.0;
d4e89f
	rgba[1] = ((code >> 16) & 0xFFu)/255.0;
d4e89f
	rgba[2] = ((code >>  8) & 0xFFu)/255.0;
d4e89f
	rgba[3] = ( code        & 0xFFu)/255.0;
d4e89f
}
d4e89f
d4e89f
unsigned int colorByRGBA(double r, double g, double b, double a) {
d4e89f
	return (colorToInt(r) << 24)
d4e89f
	     | (colorToInt(g) << 16)
d4e89f
	     | (colorToInt(b) <<  8)
d4e89f
	     |  colorToInt(a);
d4e89f
}
d4e89f
d4e89f
unsigned int colorByRGB(double r, double g, double b)
d4e89f
	{ return colorByRGBA(r, g, b, 1); }
d4e89f
d4e89f
unsigned int colorByName(const char *colorName) {
d4e89f
	unsigned int code = 0;
09c823
	
d4e89f
	const char *x = colorName;
09c823
	if (*x == '#') {
09c823
		++x;
09c823
		int hex[8] = { 0, 0, 0, 0, 0, 0, 15, 15 };
59dae5
		for(int i = 0; *x && i < 8; ++i, ++x) {
09c823
			char c = tolower(*x);
09c823
			if (c >= '0' && c <= '9') hex[i] = c - '0';
09c823
			if (c >= 'a' && c <= 'f') hex[i] = c - 'a' + 10;
09c823
		}
d4e89f
		for(int i = 0; i < 8; ++i)
d4e89f
			code |= ( hex[i] << ((7-i)*4) );
09c823
	} else
09c823
	if (isalpha(*x)) {
59dae5
		int count = (int)(sizeof(colors)/sizeof(*colors));
59dae5
		for(int i = 0; i < count; ++i) {
59dae5
			const char *a = x, *b = colors[i][0];
59dae5
			do {
59dae5
				if (tolower(*a) != tolower(*b)) break;
59dae5
				++a, ++b;
d4e89f
				if (!*a && !*b) return colorByName(colors[i][1]);
59dae5
			} while (*a && *b);
59dae5
		}
09c823
	} else {
5497ad
		double r = 0, g = 0, b = 0, a = 1;
d4e89f
		sscanf(x, "%lf %lf %lf %lf", &r, &g, &b, &a);
d4e89f
		code = colorByRGBA(r, g, b, a);
09c823
	}
d4e89f
	return code;
8535a3
}
8535a3
09c823
8eb855
static int objectsCompare(const void *a, const void *b)
8eb855
	{ return a < b ? -1 : b < a ? 1 : 0; }
8eb855
8eb855
static void* objectsKeyClone(void *k)
8eb855
	{ return k; }
8eb855
8eb855
void heliObjectRegister(void *o, HeliFreeCallback fo)
8eb855
	{ heliMapAdd(&heliObjectsSet, o, &objectsCompare, (HeliCloneCallback)objectsKeyClone, fo, NULL, NULL); }
8eb855
8eb855
void heliObjectUnregister(void *o) {
8eb855
	int i;
8eb855
	HeliPair *item = heliMapFind(&heliObjectsSet, o, &objectsCompare, &i);
8eb855
	if (item) {
8eb855
		item->freeKey = NULL;
8eb855
		heliArrayRemove(&heliObjectsSet, i);
8eb855
	}
8eb855
}