scrolling
parent
c35cda4f9b
commit
78cdbe6a05
@ -0,0 +1,6 @@
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,44 @@
|
||||
#include <time.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fmt.h"
|
||||
|
||||
//maybe should just move the whole function here
|
||||
extern double timespec_to_double(struct timespec ts);
|
||||
|
||||
struct timespec parse_time(char *str) {
|
||||
struct timespec time;
|
||||
|
||||
time_t hour_t;
|
||||
time_t min_t;
|
||||
time_t sec_t;
|
||||
time_t nsec_t;
|
||||
|
||||
sscanf(str, "%ld:%ld:%ld.%ld", &hour_t, &min_t, &sec_t, &nsec_t);
|
||||
|
||||
time.tv_sec = (hour_t * 3600) + (min_t * 60) + (sec_t);
|
||||
time.tv_nsec = nsec_t * 1e+7f;
|
||||
|
||||
//printf("%lf\n", timespec_to_double(time));
|
||||
//180.500_000_000
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
char *time_unparse(char *buffer, size_t len, struct timespec *ts) {
|
||||
struct tm *t = gmtime(&ts->tv_sec);
|
||||
if (t->tm_hour == 0 && t->tm_min != 0) {
|
||||
strftime(buffer, len, "%M:%S.", gmtime(&ts->tv_sec));
|
||||
} else if (t->tm_hour == 0 && t->tm_min == 0) {
|
||||
strftime(buffer, len, "%S.", gmtime(&ts->tv_sec));
|
||||
} else {
|
||||
strftime(buffer, len, "%T.", gmtime(&ts->tv_sec));
|
||||
}
|
||||
|
||||
double ns = timespec_to_double(*ts);
|
||||
ns = ns - (long)ns;
|
||||
snprintf(&buffer[strlen(buffer)], len, "%.2ld", (long)(ns*100));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
#ifndef FMT_H
|
||||
#define FMT_H
|
||||
|
||||
struct timespec parse_time(char *str);
|
||||
char *time_unparse(char *buffer, size_t len, struct timespec *ts);
|
||||
|
||||
#endif
|
||||
@ -1,11 +0,0 @@
|
||||
//gsl_reader.c
|
||||
#include "parser.h"
|
||||
|
||||
void init_autosplit(const char *path) {
|
||||
char *file_buffer = load_file(path);
|
||||
char *line;
|
||||
|
||||
for (line = get_next_line(file_buffer, 0); line != NULL; line = get_next_line(file_buffer, 0)) {
|
||||
printf("%s\n", line);
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
#ifndef GSL_READER
|
||||
@ -1,21 +0,0 @@
|
||||
#ifndef LAYOUT_MGR_H
|
||||
#define LAYOUT_MGR_H
|
||||
|
||||
#include <raylib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern int windowWidth;
|
||||
extern int windowHeight;
|
||||
|
||||
typedef struct layout_background {
|
||||
Texture2D texture;
|
||||
Shader shader;
|
||||
} layout_background;
|
||||
|
||||
layout_background *layout_background_new(Color color) {
|
||||
Image blank = GenImageColor(windowWidth, windowHeight, BLANK);
|
||||
Texture2D texture = LoadTextureFromImage(blank);
|
||||
UnloadImage(blank);
|
||||
}
|
||||
#endif
|
||||
@ -1,5 +0,0 @@
|
||||
#include <dlfcn.h>
|
||||
|
||||
void load_module(const char *path) {
|
||||
|
||||
}
|
||||
@ -1,155 +0,0 @@
|
||||
#include "parser.h"
|
||||
|
||||
/*
|
||||
I've separated this out into its own file
|
||||
so it can be used anywhere, and be compiled
|
||||
with any C standard that supports strtok_r.
|
||||
|
||||
*/
|
||||
|
||||
size_t get_file_len(FILE *file) {
|
||||
fseek(file, 0, SEEK_END);
|
||||
unsigned int len = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
loads a files and mallocates a buffer
|
||||
and returns a pointer to it.
|
||||
|
||||
remember to free the buffer when you're done.
|
||||
*/
|
||||
char *load_file(const char *path) {
|
||||
FILE *file = fopen(path, "r");
|
||||
if (file == NULL) {
|
||||
printf("%s\n", "Could not open file.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t len = get_file_len(file);
|
||||
|
||||
char *buffer = malloc(len);
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
fread(buffer, len, 1, file);
|
||||
fclose(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *get_next_line(char* buffer, bool clear) {
|
||||
static char *saveptr;
|
||||
static char *line;
|
||||
|
||||
if (clear) {
|
||||
saveptr = NULL;
|
||||
line = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (saveptr == NULL) {
|
||||
line = strtok_r(buffer, "\n", &saveptr);
|
||||
} else {
|
||||
if (line == NULL) {
|
||||
saveptr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line = strtok_r(NULL, "\n", &saveptr);
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
char *get_next_token(char *buffer, char *delim, bool clear) {
|
||||
static char *saveptr;
|
||||
static char *token;
|
||||
|
||||
if (clear) {
|
||||
saveptr = NULL;
|
||||
token = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (saveptr == NULL) {
|
||||
token = strtok_r(buffer, delim, &saveptr);
|
||||
} else {
|
||||
if (token == NULL) {
|
||||
saveptr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
token = strtok_r(NULL, delim, &saveptr);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
//find first non space char;
|
||||
//copy that index to beginning of string
|
||||
//replace last space with null
|
||||
char *strip(char *str, char c) {
|
||||
char *idx;
|
||||
int len = strlen(str);
|
||||
|
||||
//find index of first non space char
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (str[i] != c) {
|
||||
idx = &str[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//voodoo math
|
||||
memcpy(str, idx, len+1 - (idx - str));
|
||||
return str;
|
||||
}
|
||||
|
||||
//cut off the front
|
||||
char *cut_front(char *str, char c) {
|
||||
char *idx;
|
||||
int len = strlen(str);
|
||||
|
||||
//find index of first matching char
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (str[i] == c) {
|
||||
idx = &str[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx + 1;
|
||||
}
|
||||
|
||||
//cut off the back
|
||||
char *cut_back(char *str, char c) {
|
||||
char *idx;
|
||||
char *cpy = strdup(str);
|
||||
int len = strlen(str);
|
||||
|
||||
//find index of first matching char
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (cpy[i] == c) {
|
||||
cpy[i] = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cpy;
|
||||
}
|
||||
|
||||
//strip a string in place
|
||||
char *strip_all(char *str) {
|
||||
char *write = str;
|
||||
char *read = str;
|
||||
|
||||
do {
|
||||
if (*read != ' ') {
|
||||
*write++ = *read;
|
||||
}
|
||||
} while (*read++ && *read != ' ');
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
size_t get_file_len(FILE *file);
|
||||
char *load_file(const char *path);
|
||||
char *get_next_line(char* buffer, bool clear);
|
||||
char *get_next_token(char *buffer, char *delim, bool clear);
|
||||
char *strip_all(char *str);
|
||||
char *strip(char *str, char c);
|
||||
char *cut_front(char *str, char c);
|
||||
char *cut_back(char *str, char c);
|
||||
|
||||
#endif
|
||||
@ -1,143 +1,233 @@
|
||||
#include <raylib.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "splits.h"
|
||||
#include "parser.h"
|
||||
#include "timer.h"
|
||||
#include <math.h>
|
||||
#include "xml.h"
|
||||
#include "fmt.h"
|
||||
|
||||
#include <raylib.h>
|
||||
extern Font font;
|
||||
extern void error(const char *msg);
|
||||
|
||||
void print_segment(segment *seg) {
|
||||
printf("%s\n", seg->name);
|
||||
//printf("%ld.%ld\n", seg->realtime.tv_sec, seg->realtime.tv_nsec);
|
||||
}
|
||||
|
||||
struct timespec parse_time(char *str) {
|
||||
struct timespec time;
|
||||
//utils
|
||||
int get_file_size(FILE *file) {
|
||||
int size;
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size = ftell(file);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
time_t hour_t;
|
||||
time_t min_t;
|
||||
time_t sec_t;
|
||||
time_t nsec_t;
|
||||
void log_node(struct xml_node *node) {
|
||||
//struct xml_node *root = xml_document_root(document);
|
||||
struct xml_string *name = xml_node_name(node);
|
||||
struct xml_string *content = xml_node_content(node);
|
||||
int name_len = xml_string_length(name);
|
||||
int content_len = xml_string_length(content);
|
||||
uint8_t *name_buffer = calloc(name_len + 1, sizeof(uint8_t));
|
||||
uint8_t *content_buffer = calloc(content_len + 1, sizeof(uint8_t));
|
||||
xml_string_copy(name, name_buffer, name_len);
|
||||
xml_string_copy(content, content_buffer, content_len);
|
||||
printf("%s: %s\n", name_buffer, content_buffer);
|
||||
free(name_buffer);
|
||||
free(content_buffer);
|
||||
}
|
||||
|
||||
sscanf(str, "%ld:%ld:%ld.%ld", &hour_t, &min_t, &sec_t, &nsec_t);
|
||||
//print children of node
|
||||
void enum_node(struct xml_node *node) {
|
||||
int children;
|
||||
children = xml_node_children(node);
|
||||
|
||||
time.tv_sec = (hour_t * 3600) + (min_t * 60) + (sec_t);
|
||||
time.tv_nsec = nsec_t * 1e+7f;
|
||||
for (int i = 0; i < children; i++) {
|
||||
struct xml_node *child = xml_node_child(node, i);
|
||||
log_node(child);
|
||||
//enum_node(child);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("%lf\n", timespec_to_double(time));
|
||||
//180.500_000_000
|
||||
void enum_node_recursive(struct xml_node *node) {
|
||||
int children;
|
||||
children = xml_node_children(node);
|
||||
|
||||
return time;
|
||||
for (int i = 0; i < children; i++) {
|
||||
struct xml_node *child = xml_node_child(node, i);
|
||||
log_node(child);
|
||||
enum_node(child);
|
||||
}
|
||||
}
|
||||
|
||||
char *time_unparse(char *buffer, size_t len, struct timespec *ts) {
|
||||
struct tm *t = gmtime(&ts->tv_sec);
|
||||
if (t->tm_hour == 0 && t->tm_min != 0) {
|
||||
strftime(buffer, len, "%M:%S.", gmtime(&ts->tv_sec));
|
||||
} else if (t->tm_hour == 0 && t->tm_min == 0) {
|
||||
strftime(buffer, len, "%S.", gmtime(&ts->tv_sec));
|
||||
} else {
|
||||
strftime(buffer, len, "%T.", gmtime(&ts->tv_sec));
|
||||
}
|
||||
|
||||
double ns = timespec_to_double(*ts);
|
||||
ns = ns - (long)ns;
|
||||
snprintf(&buffer[strlen(buffer)], len, "%.2ld", (long)(ns*100));
|
||||
|
||||
return buffer;
|
||||
bool xml_name_compare(struct xml_node *node, const char *str) {
|
||||
bool equal;
|
||||
struct xml_string *name = xml_node_name(node);
|
||||
int len = xml_string_length(name);
|
||||
|
||||
uint8_t *buffer = calloc(len + 1, sizeof(uint8_t));
|
||||
xml_string_copy(name, buffer, len);
|
||||
equal = !strcmp(buffer, str);
|
||||
free(buffer);
|
||||
return equal;
|
||||
}
|
||||
|
||||
segment *read_segment(char *file, char *line) {
|
||||
segment *seg = calloc(1, sizeof(segment));
|
||||
|
||||
while (strcmp(line, "end")) {
|
||||
char *key = strip(cut_back(line, ':'), ' ');
|
||||
char *value = cut_front(strip(line, ' '), ' ');
|
||||
|
||||
typedef struct segment_nodes {
|
||||
struct xml_node **nodes;
|
||||
int count;
|
||||
} segment_nodes;
|
||||
|
||||
segment_nodes get_node_children(struct xml_node *node) {
|
||||
segment_nodes segments;
|
||||
|
||||
segments.count = xml_node_children(node);
|
||||
printf("get_node_children: %d\n", segments.count);
|
||||
segments.nodes = calloc(segments.count, sizeof(struct xml_node *));
|
||||
|
||||
for (int i = 0; i < segments.count; i++) {
|
||||
segments.nodes[i] = xml_node_child(node, i);
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "name")) {
|
||||
seg->name = strdup(value);
|
||||
}
|
||||
uint8_t *convert(struct xml_string *xml) {
|
||||
int len = xml_string_length(xml);
|
||||
uint8_t *buffer = calloc(len + 1, sizeof(uint8_t));
|
||||
xml_string_copy(xml, buffer, len);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "gametime")) {
|
||||
seg->gametime = parse_time(value);
|
||||
}
|
||||
struct xml_string *get_name_string(struct xml_node *node) {
|
||||
for (int i = 0; i < xml_node_children(node); i++) {
|
||||
struct xml_node *child = xml_node_child(node, i);
|
||||
if (xml_name_compare(child, "Name")) {
|
||||
return xml_node_content(child);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(key, "realtime")) {
|
||||
seg->realtime = parse_time(value);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "best")) {
|
||||
seg->best = parse_time(value);
|
||||
}
|
||||
uint8_t **extract(segment_nodes segments, struct xml_string *(operation)(struct xml_node *)) {
|
||||
struct xml_string **xml_strings = calloc(segments.count, sizeof(struct xml_string *));
|
||||
|
||||
for (int i = 0; i < segments.count; i++) {
|
||||
xml_strings[i] = operation(segments.nodes[i]);
|
||||
}
|
||||
|
||||
free(key);
|
||||
line = get_next_line(file, 0);
|
||||
}
|
||||
uint8_t **strings = calloc(segments.count, sizeof(uint8_t *));
|
||||
|
||||
for (int i = 0; i < segments.count; i++) {
|
||||
strings[i] = convert(xml_strings[i]);
|
||||
}
|
||||
|
||||
return seg;
|
||||
return strings;
|
||||
}
|
||||
|
||||
segment_list open_splits_file(const char *path) {
|
||||
char *file = load_file(path);
|
||||
int idx = 0;
|
||||
int cnt = 0;
|
||||
segment_list segments = {0};
|
||||
|
||||
char *line = get_next_line(file, 0);
|
||||
|
||||
//enumerate segments
|
||||
while (line != NULL) {
|
||||
if (!strcmp(line, "segment")) {
|
||||
segments.cnt++;
|
||||
}
|
||||
line = get_next_line(file, 0);
|
||||
}
|
||||
|
||||
//reset strtok_r and create fresh file since it modified it
|
||||
get_next_line(NULL, 1);
|
||||
free(file); file = load_file(path);
|
||||
|
||||
//make an extra one so the last segment->next == NULL;
|
||||
segments.list = calloc(cnt + 1, sizeof(segment *));
|
||||
|
||||
line = get_next_line(file, 0);
|
||||
|
||||
//create segments
|
||||
while (line != NULL) {
|
||||
if (!strcmp(line, "segment")) {
|
||||
segments.list[idx] = read_segment(file, line);
|
||||
idx++;
|
||||
}
|
||||
|
||||
line = get_next_line(file, 0);
|
||||
}
|
||||
struct xml_node *get_segments_node(struct xml_node *root) {
|
||||
struct xml_node *child;
|
||||
|
||||
for (int i = 0; i < xml_node_children(root); i++) {
|
||||
struct xml_node *child = xml_node_child(root, i);
|
||||
if (xml_name_compare(child, "Segments")) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
segments.list[i]->next = segments.list[i+1];
|
||||
}
|
||||
struct xml_string **get_segment_names(struct xml_node *segments) {
|
||||
int segments_count;
|
||||
struct xml_string **segment_names;
|
||||
|
||||
//check
|
||||
/*for (int i = 0; i < idx; i++) {
|
||||
printf("%p\n", segments[i]);
|
||||
}*/
|
||||
|
||||
//no leaky
|
||||
free(file);
|
||||
segments_count = xml_node_children(segments);
|
||||
|
||||
}
|
||||
|
||||
void print_all_segment_names(struct xml_node *node) {
|
||||
struct xml_node *segments = get_segments_node(node);
|
||||
if (!segments) {
|
||||
error("couldnt get em");
|
||||
}
|
||||
|
||||
return segments;
|
||||
enum_node(segments);
|
||||
}
|
||||
|
||||
/*
|
||||
void render_splits(segment_list *segments) {
|
||||
segment *create_segment(char *name) {
|
||||
segment *seg = calloc(1, sizeof(segment));
|
||||
seg->name = name;
|
||||
return seg;
|
||||
}
|
||||
|
||||
segment_list open_splits_file(const char *path) {
|
||||
FILE *xml_file = fopen(path, "r");
|
||||
if (!xml_file) {
|
||||
error("Could not open file");
|
||||
}
|
||||
|
||||
int xml_file_size = get_file_size(xml_file);
|
||||
uint8_t *buffer = calloc(sizeof(uint8_t), xml_file_size);
|
||||
int no = fread(buffer, sizeof(uint8_t), xml_file_size, xml_file);
|
||||
|
||||
struct xml_document *xml = xml_parse_document(buffer, xml_file_size);
|
||||
if (!xml) {
|
||||
error("Could not parse xml");
|
||||
}
|
||||
|
||||
printf("splits.c: parsed %s successfully\n", path);
|
||||
|
||||
int children = 0;
|
||||
struct xml_node *root = xml_document_root(xml);
|
||||
|
||||
struct xml_node *segments_node = get_segments_node(root);
|
||||
segment_nodes segments = get_node_children(segments_node);
|
||||
uint8_t **segment_names = extract(segments, get_name_string);
|
||||
|
||||
printf("open_splits_file: %d\n", segments.count);
|
||||
|
||||
for (int i = 0; i < segments.count; i++) {
|
||||
printf("%s\n", segment_names[i]);
|
||||
}
|
||||
|
||||
segment_list seglist = {0};
|
||||
printf("open_splits_file: %d\n", segments.count);
|
||||
|
||||
printf("%ld\n", segments.count * sizeof(segment));
|
||||
long long what = segments.count * sizeof(segment);
|
||||
printf("what: %lld\n", what);
|
||||
segment *segs = malloc(1008);
|
||||
printf("?\n");
|
||||
|
||||
for (int i = 0; i < segments.count; i++) {
|
||||
segs[i].name = segment_names[i];
|
||||
//segs[i].realtime = (struct timespec){0};
|
||||
}
|
||||
|
||||
seglist.segments = segs;
|
||||
seglist.count = segments.count;
|
||||
return seglist;
|
||||
}
|
||||
|
||||
|
||||
/*void render_splits(segment_list *segments) {
|
||||
char buffer[100];
|
||||
|
||||
for (int i = 0; i < segments->cnt; i++) {
|
||||
DrawTextEx(font, segments->list[i]->name, (Vector2){10, 30 * i}, (float)font.baseSize/16, 2, BLACK);
|
||||
DrawTextEx(font, time_unparse(buffer, 100, &segments->list[i]->realtime), (Vector2){200, 30 * i}, (float)font.baseSize/16, 2, BLACK);
|
||||
for (int i = 0; i < segments->count; i++) {
|
||||
DrawTextEx(font, segments->segments[i].name, (Vector2){10, 30 * i}, (float)font.baseSize/16, 2, WHITE);
|
||||
//DrawTextEx(font, time_unparse(buffer, 100, &segments->segments[i].realtime), (Vector2){200, 30 * i}, (float)font.baseSize/16, 2, BLACK);
|
||||
}
|
||||
}*/
|
||||
|
||||
void debug_print_list(segment_list *segments) {
|
||||
for (int i = 0; i < segments->count; i++) {
|
||||
printf("fucker %d\n", i);
|
||||
printf("%s\n", segments->segments[i].name);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//probably need a thing to free all the segments
|
||||
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
#include "splits.h"
|
||||
//#include "parser.h"
|
||||
#include "timer.h"
|
||||
#include "xml.h"
|
||||
#include <math.h>
|
||||
|
||||
#include <raylib.h>
|
||||
extern Font font;
|
||||
extern void error(const char *msg);
|
||||
|
||||
void print_segment(segment *seg) {
|
||||
printf("%s\n", seg->name);
|
||||
//printf("%ld.%ld\n", seg->realtime.tv_sec, seg->realtime.tv_nsec);
|
||||
}
|
||||
|
||||
/*struct timespec parse_time(char *str) {
|
||||
struct timespec time;
|
||||
|
||||
time_t hour_t;
|
||||
time_t min_t;
|
||||
time_t sec_t;
|
||||
time_t nsec_t;
|
||||
|
||||
sscanf(str, "%ld:%ld:%ld.%ld", &hour_t, &min_t, &sec_t, &nsec_t);
|
||||
|
||||
time.tv_sec = (hour_t * 3600) + (min_t * 60) + (sec_t);
|
||||
time.tv_nsec = nsec_t * 1e+7f;
|
||||
|
||||
//printf("%lf\n", timespec_to_double(time));
|
||||
//180.500_000_000
|
||||
|
||||
return time;
|
||||
}*/
|
||||
|
||||
/*char *time_unparse(char *buffer, size_t len, struct timespec *ts) {
|
||||
struct tm *t = gmtime(&ts->tv_sec);
|
||||
if (t->tm_hour == 0 && t->tm_min != 0) {
|
||||
strftime(buffer, len, "%M:%S.", gmtime(&ts->tv_sec));
|
||||
} else if (t->tm_hour == 0 && t->tm_min == 0) {
|
||||
strftime(buffer, len, "%S.", gmtime(&ts->tv_sec));
|
||||
} else {
|
||||
strftime(buffer, len, "%T.", gmtime(&ts->tv_sec));
|
||||
}
|
||||
|
||||
double ns = timespec_to_double(*ts);
|
||||
ns = ns - (long)ns;
|
||||
snprintf(&buffer[strlen(buffer)], len, "%.2ld", (long)(ns*100));
|
||||
|
||||
return buffer;
|
||||
}*/
|
||||
|
||||
//utils
|
||||
int get_file_size(FILE *file) {
|
||||
int size;
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size = ftell(file);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
void log_node(struct xml_node *node) {
|
||||
//struct xml_node *root = xml_document_root(document);
|
||||
struct xml_string *string = xml_node_name(node);
|
||||
int len = xml_string_length(string);
|
||||
uint8_t *buffer = calloc(len + 1, sizeof(uint8_t));
|
||||
xml_string_copy(string, buffer, len);
|
||||
printf("%s\n", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
segment_list open_splits_file(const char *path) {
|
||||
FILE *xml_file = fopen(path, "r");
|
||||
if (!xml_file) {
|
||||
error("Could not open file");
|
||||
}
|
||||
|
||||
int xml_file_size = get_file_size(xml_file);
|
||||
uint8_t *buffer = calloc(sizeof(uint8_t), xml_file_size);
|
||||
fread(buffer, sizeof(uint8_t), xml_file_size, xml_file);
|
||||
|
||||
|
||||
struct xml_document *xml = xml_parse_document(buffer, xml_file_size);
|
||||
if (!xml) {
|
||||
error("Could not parse xml");
|
||||
}
|
||||
|
||||
printf("parsed %s successfully\n", path);
|
||||
|
||||
return (segment_list){0};
|
||||
}
|
||||
|
||||
/*
|
||||
void render_splits(segment_list *segments) {
|
||||
char buffer[100];
|
||||
|
||||
for (int i = 0; i < segments->cnt; i++) {
|
||||
DrawTextEx(font, segments->list[i]->name, (Vector2){10, 30 * i}, (float)font.baseSize/16, 2, BLACK);
|
||||
DrawTextEx(font, time_unparse(buffer, 100, &segments->list[i]->realtime), (Vector2){200, 30 * i}, (float)font.baseSize/16, 2, BLACK);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//probably need a thing to free all the segments
|
||||
|
||||
@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Copyright (c) 2012 ooxi/xml.c
|
||||
* https://github.com/ooxi/xml.c
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from the
|
||||
* use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in a
|
||||
* product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef HEADER_XML
|
||||
#define HEADER_XML
|
||||
|
||||
|
||||
/**
|
||||
* Includes
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Opaque structure holding the parsed xml document
|
||||
*/
|
||||
struct xml_document;
|
||||
struct xml_node;
|
||||
struct xml_attribute;
|
||||
|
||||
/**
|
||||
* Internal character sequence representation
|
||||
*/
|
||||
struct xml_string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tries to parse the XML fragment in buffer
|
||||
*
|
||||
* @param buffer Chunk to parse
|
||||
* @param length Size of the buffer
|
||||
*
|
||||
* @warning `buffer` will be referenced by the document, you may not free it
|
||||
* until you free the xml_document
|
||||
* @warning You have to call xml_document_free after you finished using the
|
||||
* document
|
||||
*
|
||||
* @return The parsed xml fragment iff parsing was successful, 0 otherwise
|
||||
*/
|
||||
struct xml_document* xml_parse_document(uint8_t* buffer, size_t length);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tries to read an XML document from disk
|
||||
*
|
||||
* @param source File that will be read into an xml document. Will be closed
|
||||
*
|
||||
* @warning You have to call xml_document_free with free_buffer = true after you
|
||||
* finished using the document
|
||||
*
|
||||
* @return The parsed xml fragment iff parsing was successful, 0 otherwise
|
||||
*/
|
||||
struct xml_document* xml_open_document(FILE* source);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Frees all resources associated with the document. All xml_node and xml_string
|
||||
* references obtained through the document will be invalidated
|
||||
*
|
||||
* @param document xml_document to free
|
||||
* @param free_buffer iff true the internal buffer supplied via xml_parse_buffer
|
||||
* will be freed with the `free` system call
|
||||
*/
|
||||
void xml_document_free(struct xml_document* document, bool free_buffer);
|
||||
|
||||
|
||||
/**
|
||||
* @return xml_node representing the document root
|
||||
*/
|
||||
struct xml_node* xml_document_root(struct xml_document* document);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The xml_node's tag name
|
||||
*/
|
||||
struct xml_string* xml_node_name(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The xml_node's string content (if available, otherwise NULL)
|
||||
*/
|
||||
struct xml_string* xml_node_content(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return Number of child nodes
|
||||
*/
|
||||
size_t xml_node_children(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The n-th child or 0 if out of range
|
||||
*/
|
||||
struct xml_node* xml_node_child(struct xml_node* node, size_t child);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return Number of attribute nodes
|
||||
*/
|
||||
size_t xml_node_attributes(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the n-th attribute name or 0 if out of range
|
||||
*/
|
||||
struct xml_string* xml_node_attribute_name(struct xml_node* node, size_t attribute);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the n-th attribute content or 0 if out of range
|
||||
*/
|
||||
struct xml_string* xml_node_attribute_content(struct xml_node* node, size_t attribute);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The node described by the path or 0 if child cannot be found
|
||||
* @warning Each element on the way must be unique
|
||||
* @warning Last argument must be 0
|
||||
*/
|
||||
struct xml_node* xml_easy_child(struct xml_node* node, uint8_t const* child, ...);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return 0-terminated copy of node name
|
||||
* @warning User must free the result
|
||||
*/
|
||||
uint8_t* xml_easy_name(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return 0-terminated copy of node content
|
||||
* @warning User must free the result
|
||||
*/
|
||||
uint8_t* xml_easy_content(struct xml_node* node);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return Length of the string
|
||||
*/
|
||||
size_t xml_string_length(struct xml_string* string);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copies the string into the supplied buffer
|
||||
*
|
||||
* @warning String will not be 0-terminated
|
||||
* @warning Will write at most length bytes, even if the string is longer
|
||||
*/
|
||||
void xml_string_copy(struct xml_string* string, uint8_t* buffer, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue