This commit is contained in:
Krzosa Karol
2024-07-12 10:34:17 +02:00
parent bd97ecb9eb
commit 1ec217905d
5 changed files with 205 additions and 18 deletions

View File

@@ -0,0 +1,153 @@
struct Var {
String key;
String value;
};
struct ConfigParseResult {
Array<Var> vars;
Array<String> errors;
};
char SRTCommand[512] = "\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" --start-time {time_in_seconds} {video}";
char PDFCommand[512] = "C:/Users/Karol/AppData/Local/SumatraPDF/SumatraPDF.exe -page {page} {file}";
char TXTCommand[512] = "notepad.exe {file}";
void SkipWhitespace(String *s) {
while (s->len && IsWhitespace(s->data[0])) {
*s = s->skip(1);
}
}
String ParseWord(String *s) {
String result = {};
SkipWhitespace(s);
if (s->len && IsAlphabetic(s->data[0])) {
result = {s->data, 0};
while (s->len && IsAlphanumeric(s->data[0])) {
result.len += 1;
*s = s->skip(1);
}
}
return result;
}
bool ExpectString(String *s, String expect) {
SkipWhitespace(s);
if (StartsWith(*s, expect)) {
*s = s->skip(expect.len);
return true;
}
return false;
}
ConfigParseResult ParseConfig(Allocator allocator, String string) {
Scratch scratch;
Array<String> lines = Split(scratch, string, "\n");
ConfigParseResult result = {};
result.errors = {allocator};
result.vars = {allocator};
For(lines) {
String s = Trim(it);
if (s.len == 0) continue;
String key = ParseWord(&s);
if (key.len == 0) {
result.errors.add(Format(allocator, "failed to parse config at line: %d, the key is invalid", (int)lines.get_index(it)));
continue;
}
bool e = ExpectString(&s, "=");
if (!e) {
result.errors.add(Format(allocator, "failed to parse config at line: %d, expected '=' assignment sign", (int)lines.get_index(it)));
continue;
}
String value = Trim(s);
if (value.len == 0) {
result.errors.add(Format(allocator, "failed to parse config at line: %d, the value is invalid", (int)lines.get_index(it)));
continue;
}
result.vars.add({key, value});
}
return result;
}
String GetValue(Array<Var> vars, String key) {
For(vars) {
if (it.key == key) return it.value;
}
return {};
}
String SerializeConfig(Allocator allocator) {
String content = Format(allocator, "SRTCommand = %s\nPDFCommand = %s\nTXTCommand = %s\n", SRTCommand, PDFCommand, TXTCommand);
return content;
}
String CreateDefaultConfig(String path) {
String content = SerializeConfig(Perm);
WriteFile(path, content);
return content;
}
void LoadConfig() {
Scratch scratch;
String exe_dir = GetExeDir(scratch);
String config_path = Format(scratch, "%.*s/transcript_browser.config", FmtString(exe_dir));
String config = ReadFile(Perm, config_path);
if (config.len == 0) {
config = CreateDefaultConfig(config_path);
}
ConfigParseResult result = ParseConfig(Perm, config);
For(result.errors) {
XFileLoadResults.add({"", it});
}
String pdf_command = GetValue(result.vars, "PDFCommand");
if (pdf_command.len) {
int len = ClampTop((int)pdf_command.len, (int)sizeof(PDFCommand) - 1);
memcpy(PDFCommand, pdf_command.data, len);
PDFCommand[len] = 0;
}
String txt_command = GetValue(result.vars, "TXTCommand");
if (txt_command.len) {
int len = ClampTop((int)txt_command.len, (int)sizeof(TXTCommand) - 1);
memcpy(TXTCommand, txt_command.data, len);
TXTCommand[len] = 0;
}
String srt_command = GetValue(result.vars, "SRTCommand");
if (srt_command.len) {
int len = ClampTop((int)srt_command.len, (int)sizeof(SRTCommand) - 1);
memcpy(SRTCommand, srt_command.data, len);
SRTCommand[len] = 0;
}
}
void SaveConfig() {
Scratch scratch;
String exe_dir = GetExeDir(scratch);
String config_path = Format(scratch, "%.*s/transcript_browser.config", FmtString(exe_dir));
String content = SerializeConfig(scratch);
WriteFile(config_path, content);
}
void TestConfig() {
Scratch scratch;
{
ConfigParseResult result = ParseConfig(scratch, "\nPDFCommand = CoolCommand\nTXTCommand = ABC\nSRTCommand = DAS\n");
Assert(result.errors.len == 0);
Assert(result.vars.len == 3);
Assert(result.vars[0].key == "PDFCommand");
Assert(result.vars[1].value == "ABC");
Assert(result.vars[2].value == "DAS");
Assert(result.vars[2].key == "SRTCommand");
}
{
ConfigParseResult result = ParseConfig(scratch, "\n= CoolCommand\nTXTCommand = ABC\nSRTCommand =\n");
Assert(result.errors.len == 2);
Assert(result.vars.len == 1);
}
LoadConfig();
}