2024-10-22 13:50:52 -06:00
|
|
|
use fmt;
|
2024-10-22 15:08:08 -06:00
|
|
|
use fs;
|
2024-10-22 16:07:53 -06:00
|
|
|
use format::xdg::ini;
|
2024-10-22 13:50:52 -06:00
|
|
|
use getopt;
|
|
|
|
use io;
|
|
|
|
use locale;
|
|
|
|
use os;
|
2024-10-22 16:07:53 -06:00
|
|
|
use xdg::desktop_entry;
|
2024-10-22 13:50:52 -06:00
|
|
|
|
|
|
|
export fn main() void = {
|
|
|
|
const name = os::args[0];
|
|
|
|
|
|
|
|
const cmd = getopt::parse(
|
|
|
|
os::args,
|
|
|
|
"parse and display desktop entries",
|
2024-10-22 13:52:07 -06:00
|
|
|
('l', "locale", "the name of the locale to use"), // FIXME not working
|
2024-10-22 13:50:52 -06:00
|
|
|
('a', "action", "display a specific action"),
|
|
|
|
"file");
|
|
|
|
defer getopt::finish(&cmd);
|
|
|
|
|
|
|
|
let local = "";
|
|
|
|
let action = "";
|
|
|
|
for (let opt .. cmd.opts) switch (opt.0) {
|
|
|
|
case 'l' => local = opt.1;
|
|
|
|
case 'a' => action = opt.1;
|
|
|
|
case => abort();
|
|
|
|
};
|
|
|
|
|
|
|
|
let local = if (local == "") {
|
|
|
|
yield locale::get_messages();
|
|
|
|
} else {
|
|
|
|
yield locale::parse(local)!;
|
|
|
|
};
|
|
|
|
|
|
|
|
let file_name = if (len(cmd.args) == 1) {
|
|
|
|
yield cmd.args[0];
|
|
|
|
} else {
|
|
|
|
fmt::fprintf(os::stderr, "{}: expected 1 argument\n", name)!;
|
|
|
|
getopt::printusage(os::stderr, name, cmd.help)!;
|
|
|
|
os::exit(os::status::FAILURE);
|
|
|
|
};
|
|
|
|
|
2024-10-22 15:08:08 -06:00
|
|
|
let file = match (parse_file(file_name)) {
|
|
|
|
case let file: desktop_entry::file =>
|
|
|
|
yield file;
|
|
|
|
case let err: fs::error =>
|
|
|
|
fmt::fprintf(
|
|
|
|
os::stderr, "{}: {}: {}\n",
|
|
|
|
name, file_name, fs::strerror(err))!;
|
|
|
|
os::exit(os::status::FAILURE);
|
2024-10-22 16:07:53 -06:00
|
|
|
case let err: ini::error =>
|
2024-10-22 15:08:08 -06:00
|
|
|
fmt::fprintf(
|
|
|
|
os::stderr, "{}: {}: {}\n",
|
2024-10-22 16:07:53 -06:00
|
|
|
name, file_name, ini::strerror(err))!;
|
2024-10-22 15:08:08 -06:00
|
|
|
os::exit(os::status::FAILURE);
|
|
|
|
};
|
|
|
|
|
2024-10-22 13:50:52 -06:00
|
|
|
let result = if (action == "") {
|
|
|
|
yield print_file(file, local);
|
|
|
|
} else {
|
|
|
|
yield print_action(file, local, action);
|
|
|
|
};
|
|
|
|
|
|
|
|
match(result) {
|
2024-10-22 15:08:08 -06:00
|
|
|
case let err: io::error =>
|
|
|
|
fmt::fprintf(os::stderr, "{}: {}\n", name, io::strerror(err))!;
|
2024-10-22 13:50:52 -06:00
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-10-22 16:07:53 -06:00
|
|
|
fn parse_file (file_name: str) (desktop_entry::file | fs::error | ini::error) = {
|
2024-10-22 15:08:08 -06:00
|
|
|
let file = os::open(file_name)?;
|
|
|
|
defer io::close(file)!;
|
|
|
|
return desktop_entry::parse(file);
|
|
|
|
};
|
|
|
|
|
|
|
|
fn print_file(file: desktop_entry::file, local: locale::locale) (void | io::error) = {
|
2024-10-22 13:50:52 -06:00
|
|
|
fmt::printf("Type={}\n", file.typ)?;
|
|
|
|
fmt::printf("Version={}\n", file.version)?;
|
|
|
|
match (locale::string_resolve(file.name, local)) {
|
|
|
|
case let name: str => fmt::printf("Name={}\n", name)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
match (locale::string_resolve(file.generic_name, local)) {
|
|
|
|
case let generic_name: str => if (generic_name != "") fmt::printf("GenericName={}\n", generic_name)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
if(file.no_display) fmt::println("NoDisplay=true")?;
|
|
|
|
match (locale::string_resolve(file.comment, local)) {
|
|
|
|
case let comment: str => if (comment != "") fmt::printf("Comment={}\n", comment)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
match (locale::string_resolve(file.icon, local)) {
|
|
|
|
case let icon: str => if (icon != "") fmt::printf("Icon={}\n", icon)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
2024-10-22 15:08:08 -06:00
|
|
|
if (file.hidden) fmt::println("Hidden=true")?;
|
|
|
|
if (file.dbus_activatable) fmt::println("DBusActivatable=true")?;
|
|
|
|
if (file.try_exec != "") fmt::printf("TryExec={}\n", file.try_exec)?;
|
|
|
|
if (file.exec != "") fmt::printf("Exec={}\n", file.exec)?;
|
|
|
|
if (file.path != "") fmt::printf("Path={}\n", file.path)?;
|
|
|
|
if (file.terminal) fmt::println("Terminal=true")?;
|
|
|
|
if (len(file.mime_type) > 0) {
|
|
|
|
fmt::print("MimeType=")?;
|
|
|
|
print_strings(file.mime_type)?;
|
|
|
|
};
|
|
|
|
if (len(file.categories) > 0) {
|
|
|
|
fmt::print("Categories=")?;
|
|
|
|
print_strings(file.categories)?;
|
|
|
|
};
|
|
|
|
if (len(file.implements) > 0) {
|
|
|
|
fmt::print("Implements=")?;
|
|
|
|
print_strings(file.implements)?;
|
|
|
|
};
|
|
|
|
if (len(file.keywords) > 0) {
|
|
|
|
fmt::print("Keywords=")? ;
|
|
|
|
match (locale::strings_resolve(file.keywords, local)) {
|
|
|
|
case let keywords: []str => print_strings(keywords)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
if (file.startup_notify) fmt::println("StartupNotify=true")?;
|
|
|
|
if (file.startup_wm_class != "") fmt::printf("StartupWMClass={}\n", file.startup_wm_class)?;
|
|
|
|
if (file.url != "") fmt::printf("URL={}\n", file.url)?;
|
|
|
|
if (file.prefers_non_default_gpu) fmt::println("PrefersNonDefaultGPU=true")?;
|
|
|
|
if (file.single_main_window) fmt::println("SingleMainWindow=true")?;
|
|
|
|
};
|
|
|
|
|
|
|
|
fn print_strings(strings: []str) (void | io::error) = {
|
|
|
|
for (let string .. strings) {
|
|
|
|
fmt::printf("{};", string)?;
|
|
|
|
};
|
|
|
|
fmt::println()?;
|
2024-10-22 13:50:52 -06:00
|
|
|
};
|
|
|
|
|
2024-10-22 15:08:08 -06:00
|
|
|
fn print_action(file: desktop_entry::file, local: locale::locale, key: str) (void | io::error) = {
|
2024-10-22 13:50:52 -06:00
|
|
|
let action: (desktop_entry::action | void) = void;
|
|
|
|
for (let actio .. file.actions) {
|
|
|
|
if (actio.key == key) {
|
|
|
|
action = actio;
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let action = match (action) {
|
|
|
|
case let action: desktop_entry::action => yield action;
|
|
|
|
case void => return;
|
|
|
|
};
|
|
|
|
|
|
|
|
match (locale::string_resolve(action.name, local)) {
|
|
|
|
case let name: str => fmt::printf("Name={}\n", name)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
match (locale::string_resolve(action.icon, local)) {
|
|
|
|
case let icon: str => if (icon != "") fmt::printf("Icon={}\n", icon)?;
|
|
|
|
case void => void;
|
|
|
|
};
|
|
|
|
if (action.exec != "") fmt::printf("Exec={}\n", action.exec)?;
|
|
|
|
};
|