Add desktop file format stub

This commit is contained in:
Sasha Koshka 2024-10-03 19:52:17 -04:00
parent 218e6253e7
commit 5c911fc08d
2 changed files with 143 additions and 0 deletions

View File

@ -0,0 +1,12 @@
The desktop_entry module implements the XDG Desktop Entry Specification as
described in (https://specifications.freedesktop.org/desktop-entry-spec/latest).
Since other specifications make use of the basic desktop entry format (but with
different group names, entry requirements, etc.), this module implements:
1. The generalized format, and
2. A second processing stage to retrieve values relevant to desktop entries and
to validate them.
This module will attempt to accept malformed files for the purposes of retaining
their underlying representation, and being able to reproduce that representation
when writing updated information to the files.

View File

@ -0,0 +1,131 @@
// Represents a file of the generic key/value format used by desktop entries.
// Specification: §3
type file = struct {
preceeding_lines: []line;
groups: []group;
};
// A named group of key/value entries.
// Specification: §3.2
type group = struct {
name: str;
lines: []line;
}
// A line in the file, which can be a comment (or a blank line), an entry, or
// a localized entry.
type line = (comment | entry | localized_entry);
// A comment.
// Specification: §3.1
type comment = str;
// A key/value pair.
// Specification: §3.3
type entry = struct {
key: str;
value: value;
};
// A localized entry.
// Specification: §5
type localized_entry struct {
key: str;
value: value;
locale: locale::locale;
};
// An entry value. Values that reference memory (such as [[str]]) are borrowed
// from the [[file]]. These may be free'd or overwritten when other functions in
// this module are called, so [[value_dup]] is required to extend its lifetime.
export type value = (str, bool, f32);
// Gets a non-localized value from a file. If the group does not exist, or the
// group exists but the key isn't in it, it returns void.
export fn file_get(fil: *file, group_name: str, key: str) (value | void) {
let grou = match (file_find_group(fil, group_name)) {
case index: size => yield &file.groups[index];
case void => return void;
};
let lin = match (group_find_entry(grou, key)) {
case index: size => yield &grou.lines[index];
case void => return void;
};
match (lin) {
case entr: entry => return entr.value;
case => abort();
};
};
// Gets a localized value from a file. If the group does not exist, or the group
// exists but the key isnt in it, it returns void. If the key is in the group
// but is not localized to the specified locale, the non-localized value is
// returned.
export fn file_get_localized(
fil: *file,
group_name: str,
key: str,
local: locale,
) (value | void) {
let grou = match (file_find_group(fil, group_name)) {
case index: size => yield &file.groups[index];
case void => return void;
};
let lin = match (group_find_localized_entry(grou, key, local)) {
case index: size => yield &grou.lines[index];
case void => return void;
};
match (lin) {
case entr: localized_entry => return entr.value;
case entr: entry => return entr.value;
case => abort();
};
};
export fn file_add
export fn file_add_localized
export fn file_remove
export fn file_remove_localized
export fn file_encode
export fn file_finish
fn file_find_group (fil *file, group_name str): (size | void) = {
let index = 0;
for (let grou .. file.groups) {
if (strings::compare(group.name, group_name) == 0) {
return index;
}
index ++;
}
}
fn group_find_entry (grou *group, key str): (size | void) {
let index = 0;
for (let lin .. grou.lines) {
match (lin) {
case entr: entry =>
if (strings::compare(entry.key, entr) == 0) {
return index;
}
case => void ;
}
index ++;
}
}
// Duplicates a [[value]]. Use [[value_finish]] to get rid of it.
export fn value_dup(valu: value): value = match (valu) {
case let valu: str => yield strings.dup(valu);
case => yield valu;
};
// Frees an [[entry]] previously duplicated with [[entry_dup]].
export fn value_finish(valu: value): void = match (valu) {
case let valu: str => free(valu);
case => void;
};