- [WIP] Config files

This commit is contained in:
2023-01-17 20:04:01 +01:00
parent 4cf3987dc3
commit 4c0cf979d3
2 changed files with 119 additions and 1 deletions

115
jfile.cpp
View File

@@ -3,9 +3,18 @@
#include <stdio.h>
#include <stdint.h>
#include "jfile.h"
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <vector>
#ifndef _WIN32
#include <pwd.h>
#endif
#define DEFAULT_FILENAME "data.jrf"
#define DEFAULT_FOLDER "data/"
#define CONFIG_FILENAME "config.txt"
#pragma pack(push,1)
struct DATA_Header {
@@ -31,11 +40,18 @@ struct DATA_File {
#pragma pack(pop)
/* El std::map me fa coses rares, vaig a usar un good old std::vector amb una estructura key,value propia i au, que sempre funciona */
struct keyvalue_t {
std::string key, value;
};
char *resource_filename = NULL;
char *resource_folder = NULL;
DATA_File *data_file = NULL;
int file_source = SOURCE_FILE;
char scratch[255];
std::string config_folder = NULL;
std::vector<keyvalue_t> config;
void file_setresourcefilename(const char *str) {
if (resource_filename != NULL) free(resource_filename);
@@ -121,3 +137,102 @@ char *file_getfilebuffer(const char *resourcename, int& filesize) {
fclose(f);
return buffer;
}
// Crea la carpeta del sistema donde guardar datos
void createSystemFolder(const char *foldername)
{
#ifdef _WIN32
config_folder = std::string(getenv("APPDATA")) + "/" + foldername;
#elif __APPLE__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
config_folder = std::string(homedir) + "/Library/Application Support/" + foldername;
#elif __linux__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
config_folder = std::string(homedir) + "/." + foldername;
#endif
struct stat st = {0};
if (stat(config_folder.c_str(), &st) == -1)
{
errno = 0;
#ifdef _WIN32
int ret = mkdir(config_folder.c_str());
#else
int ret = mkdir(config_folder.c_str(), S_IRWXU);
#endif
if (ret == -1)
{
switch (errno)
{
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
}
}
void file_loadconfigvalues() {
config.clear();
std::string config_file = config_folder + "/config.txt";
FILE *f = fopen(config_file.c_str(), "r");
if (f) {
while (!feof(f)) {
char key[100], value[100];
fscanf(f, "%s = %S", key, value);
config.push_back({key, value});
}
fclose(f);
}
}
void file_saveconfigvalues() {
std::string config_file = config_folder + "/config.txt";
FILE *f = fopen(config_file.c_str(), "w");
if (f) {
for (auto pair : config) {
fprintf(f, "%s = %s\n", pair.key.c_str(), pair.value.c_str());
}
fclose(f);
}
}
const char* file_getconfigvalue(const char *key) {
if (config.empty()) file_loadconfigvalues();
for (auto pair : config) {
if (pair.key == std::string(key)) {
strcpy(scratch, pair.value.c_str());
return scratch;
}
}
return NULL;
}
void file_setconfigvalue(const char* key, const char* value) {
if (config.empty()) file_loadconfigvalues();
for (auto pair : config) {
if (pair.key == std::string(key)) {
pair.value = value;
file_saveconfigvalues();
return;
}
}
config.push_back({key, value});
file_saveconfigvalues();
return;
}

View File

@@ -10,3 +10,6 @@ void file_setsource(const int src);
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
char *file_getfilebuffer(const char *resourcename, int& filesize);
const char* file_getconfigvalue(const char *key);
void file_setconfigvalue(const char* key, const char* value);