use fmt; use io; use locale; use strings; // A line in the file, which can be a comment (or a blank line), an entry, or // a localized entry. export type line = (blank | comment | group_header | entry); // A blank line. // Specification: §3.1 export type blank = void; // A comment. // Specification: §3.1 export type comment = str; // A group header. // Specification: §3.2 export type group_header = str; // An entry in a desktop file. Entries without an explicitly stated locale are // assigned [[locale::c]]. // Specification: §3.3, §5 export type entry = struct { group: str, key: str, value: str, locale: locale::locale, }; // Duplicates an [[entry]]. Use [[entry_finish]] to get rid of it. export fn entry_dup(entr: entry) entry = entry { group = strings::dup(entr.group), key = strings::dup(entr.key), value = strings::dup(entr.value), locale = locale::dup(entr.locale), }; // Frees memory associated with an [[entry]]. export fn entry_finish(entr: entry) void = { free(entr.group); free(entr.key); free(entr.value); locale::finish(entr.locale); }; // Formats a [[line]] and writes it to an [[io::handle]]. export fn fprint(output: io::handle, lin: line) (size | io::error) = match (lin) { case blank => yield fmt::fprintln(output); case let lin: comment => yield fmt::fprintf(output, "#{}\n", lin: str); case let lin: group_header => yield fmt::fprintf(output, "[{}]\n", lin: str); case let lin: entry => let wrote = fmt::print(lin.key)?; if (!locale::equal(locale::c, lin.locale)) { let localestr = locale::format(lin.locale); defer free(localestr); wrote += fmt::printf("[{}]", localestr)?; }; wrote += fmt::printf("={}\n", lin.value)?; yield wrote; };