z_mirror/hare-fmm
git clone https://git.raiguard.me/z_mirror/hare-fmm
74b341b
trunk
1use fmt; 2use format::ini; 3use io; 4use os; 5use strings; 6 7// Configuration settings from the config file 8type config = struct { 9 mods_dir: str, 10 sets: []modset, 11}; 12 13type modset = (str, []modident); 14 15// Finds a given mod set. 16fn config_find_set(config: *config, set_name: str) (*modset | void) = { 17 for (let set &.. config.sets) { 18 if (set.0 == set_name) 19 return set; 20 }; 21}; 22 23// Frees resources related to a [[config]]. 24fn config_free(config: config) void = { 25 free(config.mods_dir); 26 for (let set &.. config.sets) { 27 free(set.0); 28 modident_free_all(set.1); 29 }; 30 free(config.sets); 31}; 32 33// Parses a configuration file entry and merges it into the config. 34fn config_handle_entry(config: *config, entry: ini::entry) void = { 35 switch (entry.0) { 36 case "sets" => 37 let set: []modident = []; 38 let mods = strings::split(entry.2, " ")!; 39 for (let mod .. mods) 40 append(set, modident_parse(mod))!; 41 append(config.sets, (strings::dup(entry.1)!, set))!; 42 case => 43 switch (entry.1) { 44 case "mods_dir" => 45 free(config.mods_dir); 46 config.mods_dir = strings::dup(entry.2)!; 47 case => 48 void; 49 }; 50 }; 51}; 52 53// Parses and returns configuration options from the config file. Defaults will 54// be provided if they are not specified or the config file does not exist. 55// The return value must be freed with [[config_free]]. 56fn config_parse(path: str) config = { 57 const cwd = os::getcwd(); 58 let config = config { 59 mods_dir = strings::dup(cwd)!, 60 sets = [] 61 }; 62 63 const config_file = os::open(path); 64 if (config_file is io::file) { 65 const config_file = config_file as io::file; 66 defer io::close(config_file)!; 67 let scanner = ini::scan(config_file); 68 defer ini::finish(&scanner); 69 for (let entry => ini::next(&scanner)!) { 70 config_handle_entry(&config, entry); 71 }; 72 }; 73 74 return config; 75};