Compare commits
6 Commits
9ede109998
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d061e74ea | |||
| b95829bd05 | |||
| 2644932686 | |||
| 21bc239cef | |||
| fdcef60130 | |||
| 4861950176 |
@@ -1,10 +1,11 @@
|
||||
use fmt;
|
||||
use fs;
|
||||
use format::desktop_entry;
|
||||
use format::xdg::ini;
|
||||
use getopt;
|
||||
use io;
|
||||
use locale;
|
||||
use os;
|
||||
use xdg::desktop_entry;
|
||||
|
||||
export fn main() void = {
|
||||
const name = os::args[0];
|
||||
@@ -47,10 +48,10 @@ export fn main() void = {
|
||||
os::stderr, "{}: {}: {}\n",
|
||||
name, file_name, fs::strerror(err))!;
|
||||
os::exit(os::status::FAILURE);
|
||||
case let err: desktop_entry::error =>
|
||||
case let err: ini::error =>
|
||||
fmt::fprintf(
|
||||
os::stderr, "{}: {}: {}\n",
|
||||
name, file_name, desktop_entry::strerror(err))!;
|
||||
name, file_name, ini::strerror(err))!;
|
||||
os::exit(os::status::FAILURE);
|
||||
};
|
||||
|
||||
@@ -67,7 +68,7 @@ export fn main() void = {
|
||||
};
|
||||
};
|
||||
|
||||
fn parse_file (file_name: str) (desktop_entry::file | fs::error | desktop_entry::error) = {
|
||||
fn parse_file (file_name: str) (desktop_entry::file | fs::error | ini::error) = {
|
||||
let file = os::open(file_name)?;
|
||||
defer io::close(file)!;
|
||||
return desktop_entry::parse(file);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The desktop_entry module implements the basic format used by the XDG Desktop
|
||||
The ini module implements the basic INI-like format used by 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
|
||||
@@ -34,12 +34,12 @@ use os;
|
||||
locale::parse("en_US")!),
|
||||
entry_new(
|
||||
h_dac, "Name", "Zweep zoop flooble glorp",
|
||||
locale::parse("xx_XX.UTF-8")!),
|
||||
locale::parse("xx_XX")!),
|
||||
"Another comment": comment,
|
||||
entry_new(h_dac, "Icon", "fooview-new", locale::c),
|
||||
];
|
||||
|
||||
let file = os::open("format/desktop_entry/test_data/foo.desktop")!;
|
||||
let file = os::open("format/xdg/ini/test_data/foo.desktop")!;
|
||||
defer io::close(file)!;
|
||||
let scanne = scan(file);
|
||||
defer finish(&scanne);
|
||||
@@ -83,11 +83,11 @@ use os;
|
||||
locale::parse("en_US")!),
|
||||
entry_new(
|
||||
h_dac, "Name", "Zweep zoop flooble glorp",
|
||||
locale::parse("xx_XX.UTF-8")!),
|
||||
locale::parse("xx_XX")!),
|
||||
entry_new(h_dac, "Icon", "fooview-new", locale::c),
|
||||
];
|
||||
|
||||
let file = os::open("format/desktop_entry/test_data/foo.desktop")!;
|
||||
let file = os::open("format/xdg/ini/test_data/foo.desktop")!;
|
||||
defer io::close(file)!;
|
||||
let scanne = scan(file);
|
||||
defer finish(&scanne);
|
||||
@@ -109,7 +109,7 @@ use os;
|
||||
assert(entry_equal(parse_entry("hello[sr_YU.UTF-8@Latn]=world")!, entry {
|
||||
key = "hello",
|
||||
value = "world",
|
||||
locale = locale::parse("sr_YU.UTF-8@Latn")!,
|
||||
locale = locale::parse("sr_YU@Latn")!,
|
||||
...
|
||||
}));
|
||||
};
|
||||
2
xdg/basedir/README
Normal file
2
xdg/basedir/README
Normal file
@@ -0,0 +1,2 @@
|
||||
The basedir module implements the XDG Base Directory Specification as described
|
||||
in (https://specifications.freedesktop.org/basedir-spec/latest/).
|
||||
98
xdg/basedir/basedir.ha
Normal file
98
xdg/basedir/basedir.ha
Normal file
@@ -0,0 +1,98 @@
|
||||
// Returns the single base directory relative to which user-specific data files
|
||||
// should be written, which is defined by $XDG_DATA_HOME. If $XDG_DATA_HOME is
|
||||
// either not set or empty, a default equal to $HOME/.local/share is used.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn data_home (prog: str = "") str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the single base directory relative to which user-specific
|
||||
// configuration files should be written, which is defined by $XDG_CONFIG_HOME.
|
||||
// If $XDG_CONFIG_HOME is either not set or empty, a default equal to
|
||||
// $HOME/.config is used.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.s
|
||||
export fn config_home (prog: str = "") str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the single base directory relative to which user-specific state data
|
||||
// that should persist between (application) restarts, but that is not important
|
||||
// or portable enough to the user that it should be stored. It is defined by
|
||||
// $XDG_STATE_HOME. It may contain:
|
||||
//
|
||||
// - actions history (logs, history, recently used files, …)
|
||||
// - current state of the application that can be reused on a restart (view,
|
||||
// layout, open files, undo history, …)
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn state_home (prog: str = "") str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// CacheHome returns the single base directory relative to which user-specific
|
||||
// non-essential (cached) data should be written, which is defined by
|
||||
// $XDG_CACHE_HOME. If $XDG_CACHE_HOME is either not set or empty, a default
|
||||
// equal to $HOME/.cache is used.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn cache_home (prog: str = "") str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the single base directory relative to which user-specific runtime
|
||||
// files and other file objects should be placed, which is defined by
|
||||
// $XDG_RUNTIME_DIR. This module does not provide a fallback directory. If this
|
||||
// function returns an error, applications should fall back to a replacement
|
||||
// directory with similar capabilities (in accordance with §3) and print a
|
||||
// warning message.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn runtime_dir (prog: str = "") str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the set of preference ordered base directories relative to which data
|
||||
// files should be searched, which is defined by $XDG_DATA_DIRS. If
|
||||
// $XDG_DATA_DIRS is either not set or empty, a value equal to
|
||||
// /usr/local/share/:/usr/share/ is used. It is reccomended to call [[data_all]]
|
||||
// instead for most use cases.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn data_dirs (prog: str = "") []str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns set of preference ordered base directories relative to which
|
||||
// configuration files should be searched, which is defined by $XDG_CONFIG_DIRS.
|
||||
// If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg is
|
||||
// used. It is reccomended to call [[config_all]] instead for most use cases.
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn config_dirs (prog: str = "") []str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the result of [[data_home]] in front of [[data_dirs]].
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn data_all (prog: str = "") []str = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
// Returns the result of [[config_home]] in front of [[config_dirs]].
|
||||
//
|
||||
// The memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dup]] to extend its lifetime.
|
||||
export fn config_all (prog: str = "") []str = {
|
||||
// TODO
|
||||
};
|
||||
@@ -1,3 +1,3 @@
|
||||
The desktop_entry module implements the XDG Desktop Entry Specification as
|
||||
described in (https://specifications.freedesktop.org/desktop-entry-spec/latest).
|
||||
For the generalized format, see [[format::desktop_entry]].
|
||||
For the generalized format, see [[format::xdg::ini]].
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use format::desktop_entry;
|
||||
use format::xdg::ini;
|
||||
use io;
|
||||
use locale;
|
||||
use strings;
|
||||
@@ -44,14 +44,14 @@ export type action = struct {
|
||||
};
|
||||
|
||||
// Parses a desktop entry file. Use [[file_finish]] to get rid of it.
|
||||
export fn parse(input: io::handle) (file | desktop_entry::error) = {
|
||||
export fn parse(input: io::handle) (file | ini::error) = {
|
||||
let file = file { ... };
|
||||
let scanne = desktop_entry::scan(input);
|
||||
defer desktop_entry::finish(&scanne);
|
||||
let scanne = ini::scan(input);
|
||||
defer ini::finish(&scanne);
|
||||
|
||||
for (let entr => desktop_entry::next_entry(&scanne)?) {
|
||||
for (let entr => ini::next_entry(&scanne)?) {
|
||||
match(parse_handle_entry(&file, entr)) {
|
||||
case let err: desktop_entry::error =>
|
||||
case let err: ini::error =>
|
||||
finish(&file);
|
||||
return err;
|
||||
case void => void;
|
||||
@@ -90,17 +90,17 @@ export fn finish(this: *file) void = {
|
||||
free(this.actions);
|
||||
};
|
||||
|
||||
fn parse_handle_entry(this: *file, entr: desktop_entry::entry) (void | desktop_entry::error) = {
|
||||
fn parse_handle_entry(this: *file, entr: ini::entry) (void | ini::error) = {
|
||||
const desktop_action_prefix = "Desktop Action ";
|
||||
if (entr.group == "Desktop Entry") {
|
||||
return parse_handle_desktop_entry_entry(this, entr);
|
||||
return parse_handle_ini_entry(this, entr);
|
||||
} else if (strings::hasprefix(entr.group, desktop_action_prefix)) {
|
||||
let key = strings::trimprefix(entr.group, desktop_action_prefix);
|
||||
return parse_handle_desktop_action_entry(this, entr, key);
|
||||
};
|
||||
};
|
||||
|
||||
fn parse_handle_desktop_action_entry(this: *file, entr: desktop_entry::entry, key: str) (void | desktop_entry::error) = {
|
||||
fn parse_handle_desktop_action_entry(this: *file, entr: ini::entry, key: str) (void | ini::error) = {
|
||||
let actio = match(parse_find_action(this, key)) {
|
||||
case let actio: *action => yield actio;
|
||||
case void => return void;
|
||||
@@ -108,70 +108,70 @@ fn parse_handle_desktop_action_entry(this: *file, entr: desktop_entry::entry, ke
|
||||
if (entr.key == "Name") {
|
||||
parse_set_locale_string(
|
||||
&actio.name, entr.locale,
|
||||
desktop_entry::parse_localestring(entr.value)?);
|
||||
ini::parse_localestring(entr.value)?);
|
||||
} else if (entr.key == "Icon") {
|
||||
parse_set_locale_string(
|
||||
&actio.icon, entr.locale,
|
||||
desktop_entry::parse_iconstring(entr.value)?);
|
||||
ini::parse_iconstring(entr.value)?);
|
||||
} else if (entr.key == "Exec") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
actio.exec = desktop_entry::parse_string(entr.value)?;
|
||||
actio.exec = ini::parse_string(entr.value)?;
|
||||
};
|
||||
};
|
||||
|
||||
fn parse_handle_desktop_entry_entry(this: *file, entr: desktop_entry::entry) (void | desktop_entry::error) = {
|
||||
fn parse_handle_ini_entry(this: *file, entr: ini::entry) (void | ini::error) = {
|
||||
if (entr.key == "Type") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.typ = desktop_entry::parse_string(entr.value)?;
|
||||
this.typ = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "Version") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.version = desktop_entry::parse_string(entr.value)?;
|
||||
this.version = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "Name") {
|
||||
parse_set_locale_string(
|
||||
&this.name, entr.locale,
|
||||
desktop_entry::parse_localestring(entr.value)?);
|
||||
ini::parse_localestring(entr.value)?);
|
||||
} else if (entr.key == "GenericName") {
|
||||
parse_set_locale_string(
|
||||
&this.generic_name, entr.locale,
|
||||
desktop_entry::parse_localestring(entr.value)?);
|
||||
ini::parse_localestring(entr.value)?);
|
||||
} else if (entr.key == "NoDisplay") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.no_display = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.no_display = ini::parse_boolean(entr.value)?;
|
||||
} else if (entr.key == "Comment") {
|
||||
parse_set_locale_string(
|
||||
&this.comment, entr.locale,
|
||||
desktop_entry::parse_localestring(entr.value)?);
|
||||
ini::parse_localestring(entr.value)?);
|
||||
} else if (entr.key == "Icon") {
|
||||
parse_set_locale_string(
|
||||
&this.icon, entr.locale,
|
||||
desktop_entry::parse_iconstring(entr.value)?);
|
||||
ini::parse_iconstring(entr.value)?);
|
||||
} else if (entr.key == "Hidden") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.hidden = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.hidden = ini::parse_boolean(entr.value)?;
|
||||
} else if (entr.key == "OnlyShowIn") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.only_show_in = desktop_entry::parse_strings(entr.value)?;
|
||||
this.only_show_in = ini::parse_strings(entr.value)?;
|
||||
} else if (entr.key == "NotShowIn") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.not_show_in = desktop_entry::parse_strings(entr.value)?;
|
||||
this.not_show_in = ini::parse_strings(entr.value)?;
|
||||
} else if (entr.key == "DBusActivatable") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.dbus_activatable = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.dbus_activatable = ini::parse_boolean(entr.value)?;
|
||||
} else if (entr.key == "TryExec") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.try_exec = desktop_entry::parse_string(entr.value)?;
|
||||
this.try_exec = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "Exec") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.exec = desktop_entry::parse_string(entr.value)?;
|
||||
this.exec = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "Path") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.path = desktop_entry::parse_string(entr.value)?;
|
||||
this.path = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "Terminal") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.terminal = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.terminal = ini::parse_boolean(entr.value)?;
|
||||
} else if (entr.key == "Actions") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
let strings =desktop_entry::parse_strings(entr.value)?;
|
||||
let strings =ini::parse_strings(entr.value)?;
|
||||
defer free(strings);
|
||||
this.actions = alloc([], len(strings));
|
||||
for (let string .. strings) {
|
||||
@@ -182,33 +182,33 @@ fn parse_handle_desktop_entry_entry(this: *file, entr: desktop_entry::entry) (vo
|
||||
};
|
||||
} else if (entr.key == "MimeType") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.mime_type = desktop_entry::parse_strings(entr.value)?;
|
||||
this.mime_type = ini::parse_strings(entr.value)?;
|
||||
} else if (entr.key == "Categories") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.categories = desktop_entry::parse_strings(entr.value)?;
|
||||
this.categories = ini::parse_strings(entr.value)?;
|
||||
} else if (entr.key == "Implements") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.implements = desktop_entry::parse_strings(entr.value)?;
|
||||
this.implements = ini::parse_strings(entr.value)?;
|
||||
} else if (entr.key == "Keywords") {
|
||||
parse_set_locale_strings(
|
||||
&this.keywords, entr.locale,
|
||||
desktop_entry::parse_localestrings(entr.value)?);
|
||||
ini::parse_localestrings(entr.value)?);
|
||||
} else if (entr.key == "StartupWMClass") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.startup_wm_class = desktop_entry::parse_string(entr.value)?;
|
||||
this.startup_wm_class = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "URL") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.url = desktop_entry::parse_string(entr.value)?;
|
||||
this.url = ini::parse_string(entr.value)?;
|
||||
} else if (entr.key == "PrefersNonDefaultGPU") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.prefers_non_default_gpu = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.prefers_non_default_gpu = ini::parse_boolean(entr.value)?;
|
||||
} else if (entr.key == "SingleMainWindow") {
|
||||
if (parse_is_localized(entr)) return void;
|
||||
this.single_main_window = desktop_entry::parse_boolean(entr.value)?;
|
||||
this.single_main_window = ini::parse_boolean(entr.value)?;
|
||||
};
|
||||
};
|
||||
|
||||
fn parse_is_localized(entr: desktop_entry::entry) bool = {
|
||||
fn parse_is_localized(entr: ini::entry) bool = {
|
||||
return !locale::equal(entr.locale, locale::c);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use format::desktop_entry;
|
||||
use format::xdg::ini;
|
||||
use fmt;
|
||||
use io;
|
||||
use locale;
|
||||
use os;
|
||||
|
||||
@test fn parse() void = {
|
||||
let file = os::open("format/desktop_entry/test_data/foo_full.desktop")!;
|
||||
let file = os::open("format/xdg/ini/test_data/foo_full.desktop")!;
|
||||
defer io::close(file)!;
|
||||
let file = parse(file)!;
|
||||
defer finish(&file);
|
||||
|
||||
10
xdg/icon_theme/dirs.ha
Normal file
10
xdg/icon_theme/dirs.ha
Normal file
@@ -0,0 +1,10 @@
|
||||
// Returns the set of directories in which themes should be looked for in order
|
||||
// of preference. It will return $HOME/.icons (for backwards compatibility),
|
||||
// $XDG_DATA_DIRS/icons, and /usr/share/pixmaps. Applications may further add
|
||||
// their own icon directories to this list.
|
||||
//
|
||||
// This memory is statically allocated and must not be free'd. It may be
|
||||
// overwritten later, so use [[strings::dupall]] to extend its lifetime.
|
||||
export fn theme_dirs() ([]str | error) = {
|
||||
// TODO
|
||||
};
|
||||
Reference in New Issue
Block a user