proclib/src/ktkStructure.c

330 lines
9.4 KiB
C

#include "ktkStructure.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h> // for randomizeSeed
unsigned long ktk_RANDOM_SEED = 1;
unsigned long ktk_randomizeSeed() {
ktk_RANDOM_SEED = (unsigned long)time(0);
#if _WIN32 | _WIN64
srand(ktk_RANDOM_SEED);
#else
srandom(ktk_RANDOM_SEED);
#endif
return ktk_RANDOM_SEED;
}
int ktk_getRandom(int min, int max) {
int num;
if (min == 0 && max == 0) return 0;
if (min == max) return min;
// include max as a possible number (+1)
int range = (max+1) - min;
if (range >= RAND_MAX) {
printf("ktk_getRandom(%d, %d): ERROR, range beyond RAND_MAX!\n", min, max);
return 0;
} else if (range == 0) {
return min;
}
int buckets = RAND_MAX / range;
int limit = buckets * range;
#if _WIN32 | _WIN64
for (num = rand(); num >= limit; num = rand());
#else
for (num = random(); num >= limit; num = random());
#endif
return min + (num / buckets);
}
int ktk_rollNumber(struct ktkNumber number) {
return (ktk_getRandom(number.a, number.b));
if (number.type == ktk_PERCENT) {
} else if (number.type == ktk_DIGIT) {
}
}
int ktk_rollNumberSet(struct ktkNumberSet set) {
if (set.count <= 0) return 0;
return ktk_rollNumber(set.sets[ktk_getRandom(0, set.count-1)]);
}
int ktk_deleteNumberSet(struct ktkNumberSet *set) {
if (set->sets != NULL) {
free(set->sets);
set->sets = NULL;
set->count = 0;
}
return 0;
}
int ktk_copyNumberSet(struct ktkNumberSet *set_1, struct ktkNumberSet *set_2) {
ktk_deleteNumberSet(set_2);
if (set_1->count > 0) {
set_2->sets = realloc(set_2->sets, set_1->count*sizeof(struct ktkNumber));
memcpy(set_2->sets, set_1->sets, set_1->count*sizeof(struct ktkNumber));
set_2->count = set_1->count;
} else {
return 1;
}
return 0;
}
/*ktkField_t ktkStructureTable[] = {
{FIELD(flags)},
{FIELD(x)}, {FIELD(y)},
{FIELD(size_x)}, {FIELD(size_y)},
{FIELD(id_1)}, {FIELD(id_2)},
{FIELD(data)},
{FIELD(relations)}, {FIELD(relation_count)}
};
*/
//int ktk_setField(ktkField_t *table, size_t table_size,
const struct ktkStructure ktk_STRUCTURE_DEFAULT = {
0,
NULL,
{ 0, 0, 0}, { 0, 0, 0}, // x, y
{ 0, 0, 0}, { 0, 0, 0}, // size_x, size_y
{ NULL, 0}, // id_1
{ NULL, 0}, // id_2
{ NULL, 0}, // id_1 replace rules
{ NULL, 0}, // id_2 replace rules
NULL,
NULL, 0, // relations
NULL, 0 // paths + path count
};
void ktk_dumpStructure(struct ktkStructure *structure) {
printf("flags: %d\n", structure->flags);
printf("name: %s\n", structure->name);
printf("x: %dx%d\n", structure->x.a, structure->x.b);
printf("y: %dx%d\n", structure->y.a, structure->y.b);
printf("size_x: %dx%d\n", structure->size_x.a, structure->size_x.b);
printf("size_y: %dx%d\n", structure->size_y.a, structure->size_y.b);
}
int ktk_deleteStructure(struct ktkStructure *structure) {
if (structure->name != NULL) {
free(structure->name);
structure->name = NULL;
}
ktk_deleteNumberSet(&structure->id_1);
ktk_deleteNumberSet(&structure->id_2);
ktk_deleteNumberSet(&structure->replace_id_1);
ktk_deleteNumberSet(&structure->replace_id_2);
if (structure->relation_count > 0) {
int i;
for (i = 0; i < structure->relation_count; i++) {
//ktk_deleteLive(structure->relations[i]);
//free(structure->relations[i]);
free(structure->relations[i].name);
}
free(structure->relations);
structure->relations = NULL;
structure->relation_count = 0;
}
if (structure->path_count > 0) {
int i;
for (i = 0; i < structure->path_count; i++) {
free(structure->paths[i].name);
free(structure->paths[i].to);
free(structure->paths[i].from);
ktk_deleteNumberSet(&(structure->paths[i].to_x));
ktk_deleteNumberSet(&(structure->paths[i].to_y));
ktk_deleteNumberSet(&(structure->paths[i].from_x));
ktk_deleteNumberSet(&(structure->paths[i].from_y));
ktk_deleteNumberSet(&(structure->paths[i].x));
ktk_deleteNumberSet(&(structure->paths[i].y));
}
free(structure->paths);
structure->paths = NULL;
structure->path_count = 0;
}
return 0;
}
const struct ktkRelation ktk_RELATION_DEFAULT = {
0,
NULL,
{ 0, 0, 0}, { 0, 0, 0},
{ 0, 0, 0}, { 0, 0, 0},
{ 1, 1, ktk_DIGIT},
};
const struct ktkLive ktk_LIVE_DEFAULT = {
NULL, // name of this
NULL, // parent
NULL, 0, // children and count
NULL, 0, // record pathing links + count of links
0,
0, 0, // x, y
0, 0, // size
0, 0, // id_1, id_2
NULL, // data
NULL // map?
};
struct ktkLive *ktk_getLiveRoot(struct ktkLive *live) {
struct ktkLive *current_live = live;
while (current_live->parent != NULL) {
current_live = current_live->parent;
}
return current_live;
}
struct ktkLive *ktk_getLive(struct ktkLive *live, const char *get, int match_offset) {
if (get == NULL) return NULL;
printf("offset: %d\n", match_offset);
struct ktkLive *current_live = live;
size_t get_len = strlen(get);
size_t get_offset = 0;
while (get_offset < get_len+1) {
if (get[get_offset] == ':') {
current_live = ktk_getLiveRoot(current_live);
get_offset++;
} else if (get[get_offset] == '^') {
if (current_live->parent != NULL) {
current_live = current_live->parent;
} else {
printf("could not get requested parent of %s\n", current_live->name);
return NULL;
}
get_offset++;
} else if (get[get_offset] == '\0') {
if (current_live == live) return NULL;
return current_live;
} else {
size_t sub_offset = get_offset;
while((get[sub_offset] != '^' && get[sub_offset] != ':')) {
if (get[sub_offset] == '\0') break;
sub_offset++;
}
char sub_name[sub_offset - get_offset+1];
memcpy(&sub_name, get+get_offset, sub_offset - get_offset);
sub_name[sub_offset-get_offset] = '\0';
size_t i;
int found = 0;
int match_current = 0;
for (i = 0; i < current_live->child_count; i++) {
if (strcmp(sub_name, current_live->children[i]->name) == 0) {
if (current_live->children[i] == current_live) continue; // we don't match ourself
if (get[sub_offset] == '\0') {
match_current++;
if (match_current > match_offset) {
current_live = current_live->children[i];
get_offset = sub_offset+1;
found = 1;
break;
}
} else {
current_live = current_live->children[i];
get_offset = sub_offset+1;
found = 1;
break;
}
}
}
if (!found) {
printf("could not find %s!\n", sub_name);
return NULL;
}
}
}
if (current_live == live) return NULL;
return current_live;
}
int ktk_addLink(struct ktkLive *live_1, struct ktkLive *live_2) {
live_1->link_count++;
live_1->links = realloc(live_1->links, live_1->link_count*sizeof(struct ktkLive*));
live_1->links[live_1->link_count-1] = live_2;
return 0;
}
int ktk_containsLink(struct ktkLive *live_1, struct ktkLive *live_2) {
int i;
for (i = 0; i < live_1->link_count; i++) {
if (live_1->links[i] == live_2) {
return 1;
}
}
return 0;
}
int ktk_deleteLive(struct ktkLive *live) {
if (live->name != NULL) {
free(live->name);
live->name = NULL;
}
if (live->child_count > 0) {
int i;
for (i = 0; i < live->child_count; i++) {
ktk_deleteLive(live->children[i]);
free(live->children[i]);
}
free(live->children);
live->children = NULL;
live->child_count = 0;
}
if (live->link_count > 0) {
free(live->links);
live->links = NULL;
}
return 0;
}
int ktk_addLiveChild(struct ktkLive *parent, struct ktkLive *child) {
parent->child_count++;
parent->children = realloc(parent->children, parent->child_count*sizeof(struct ktkLive*));
parent->children[parent->child_count-1] = child;
child->parent = parent;
return 0;
}
int ktk_setLiveName(struct ktkLive *live, const char *name) {
if (live->name != NULL) {
free(live->name);
live->name = NULL;
}
int size = strlen(name)+1;
live->name = malloc(size);
memcpy(live->name, name, size);
return 0;
}
const struct ktkPath ktk_PATH_DEFAULT = {
NULL, // pathing structure name
NULL, // pathing structure
0, // pathing flags
NULL, 0, // target structure in pathing syntax, target flags
{NULL, 0}, // to x offset
{NULL, 0}, // to y offset
NULL, 0, // from structure in pathing syntax, from flags
{NULL, 0}, // from x offset
{NULL, 0}, // from y offset
{NULL, 0}, // x offset
{NULL, 0} // y offset
};
int ktk_explodeString(const char *string, char delim, int depth, char ***results) {
int words = 0, word_size = 1, word_i = 0;
int i = 0;
int len = strlen(string)+1;
// TODO: resize in 8-byte chunks or so
*results = malloc(1*sizeof(char*));
(*results)[words] = malloc(1*sizeof(char));
for (i = 0; i < len; i++) {
if ((string[i] == delim && words < depth) || string[i] == '\0') {
(*results)[words][word_i] = '\0';
*results = realloc(*results, (++words+1)*sizeof(char*));
(*results)[words] = malloc(1*sizeof(char));
//(*results)[words][0] = '\0';
word_i = 0;
word_size = 1;
} else {
(*results)[words] = realloc((*results)[words], ++word_size*sizeof(char));
(*results)[words][word_i++] = string[i];
}
}
return words;
}