diff --git a/daemon/command.c b/daemon/command.c index af746c4..0f033cd 100644 --- a/daemon/command.c +++ b/daemon/command.c @@ -208,40 +208,9 @@ static void cmd_config(char *buffer, int *buflen, int argc, char **argv) ERR_fmt("Unknown subcommand '%s' for 'config' command", argv[1]); } -struct level_map { - int level; - const char *string; -}; - -static int lmap_get_level(const struct level_map *map, const char *string, int notfound) -{ - int i; - - for (i = 0; map[i].string != NULL; i++) { - if (strcasecmp(map[i].string, string) == 0) { - return map[i].level; - } - } - - return notfound; -} - -static const char *lmap_get_string(const struct level_map *map, int level) -{ - int i; - - for (i = 0; map[i].string != NULL; i++) { - if (map[i].level == level) { - return map[i].string; - } - } - - return NULL; -} - -#define DATA_LMAP(map, level, resp) do {\ +#define DATA_LMAP(level, resp) do {\ int input_level_ ## __LINE__ = level; \ - const char *lmap_level_ ## __LINE__ = lmap_get_string(map, input_level_ ## __LINE__); \ + const char *lmap_level_ ## __LINE__ = lookup_level_by_id(input_level_ ## __LINE__); \ char lmap_unknown_level ## __LINE__[32] = {0}; \ if (lmap_level_ ## __LINE__ == NULL) { \ snprintf(lmap_unknown_level ## __LINE__, sizeof(lmap_unknown_level ## __LINE__), \ @@ -252,47 +221,8 @@ static const char *lmap_get_string(const struct level_map *map, int level) } while(0) -static int array_find_index(const char **array, int nmemb, const char *string) -{ - int i; - - for (i = 0; i < nmemb; i++) { - if (strcasecmp(array[i], string) == 0) { - return i; - } - } - - return nmemb; -} - static void cmd_logging(char *buffer, int *buflen, int argc, char **argv) { - static const char *modules[X52D_MOD_MAX] = { - [X52D_MOD_CONFIG] = "config", - [X52D_MOD_CLOCK] = "clock", - [X52D_MOD_DEVICE] = "device", - [X52D_MOD_IO] = "io", - [X52D_MOD_LED] = "led", - [X52D_MOD_MOUSE] = "mouse", - [X52D_MOD_COMMAND] = "command", - [X52D_MOD_CLIENT] = "client", - [X52D_MOD_NOTIFY] = "notify", - [X52D_MOD_KEYBOARD_LAYOUT] = "keyboard_layout", - }; - - // This corresponds to the levels in pinelog - static const struct level_map loglevels[] = { - {PINELOG_LVL_NOTSET, "default"}, - {PINELOG_LVL_NONE, "none"}, - {PINELOG_LVL_FATAL, "fatal"}, - {PINELOG_LVL_ERROR, "error"}, - {PINELOG_LVL_WARNING, "warning"}, - {PINELOG_LVL_INFO, "info"}, - {PINELOG_LVL_DEBUG, "debug"}, - {PINELOG_LVL_TRACE, "trace"}, - {0, NULL}, - }; - if (argc < 2) { ERR("Insufficient arguments for 'logging' command"); return; @@ -301,13 +231,13 @@ static void cmd_logging(char *buffer, int *buflen, int argc, char **argv) // logging show [module] MATCH(1, "show") { if (argc == 2) { - DATA_LMAP(loglevels, pinelog_get_level(), "global"); + DATA_LMAP(pinelog_get_level(), "global"); } else if (argc == 3) { - int module = array_find_index(modules, X52D_MOD_MAX, argv[2]); - if (module == X52D_MOD_MAX) { + int module = lookup_module_by_name(argv[2]); + if (module == INT_MAX) { ERR_fmt("Invalid module '%s'", argv[2]); } else { - DATA_LMAP(loglevels, pinelog_get_module_level(module), argv[2]); + DATA_LMAP(pinelog_get_module_level(module), argv[2]); } } else { ERR_fmt("Unexpected arguments for 'logging show' command; got %d, expected 2 or 3", argc); @@ -319,7 +249,7 @@ static void cmd_logging(char *buffer, int *buflen, int argc, char **argv) // logging set [module] MATCH(1, "set") { if (argc == 3) { - int level = lmap_get_level(loglevels, argv[2], INT_MAX); + int level = lookup_level_by_name(argv[2]); if (level == INT_MAX) { ERR_fmt("Unknown level '%s' for 'logging set' command", argv[2]); } else if (level == PINELOG_LVL_NOTSET) { @@ -329,10 +259,10 @@ static void cmd_logging(char *buffer, int *buflen, int argc, char **argv) OK("logging", "set", argv[2]); } } else if (argc == 4) { - int level = lmap_get_level(loglevels, argv[3], INT_MAX); - int module = array_find_index(modules, X52D_MOD_MAX, argv[2]); + int level = lookup_level_by_name(argv[3]); + int module = lookup_module_by_name(argv[2]); - if (module == X52D_MOD_MAX) { + if (module == INT_MAX) { ERR_fmt("Invalid module '%s'", argv[2]); return; } diff --git a/daemon/config_registry.json b/daemon/config_registry.json new file mode 100644 index 0000000..f69c8c5 --- /dev/null +++ b/daemon/config_registry.json @@ -0,0 +1,54 @@ +{ + "_comment": "The configuration registry is a historic record of\nall configuration identifiers. Do NOT edit this file manually, or else, the\ncommunication protocol may break.", + "sections": { + "CLOCK": 1, + "LED": 2, + "BRIGHTNESS": 3, + "MOUSE": 4, + "PROFILES": 5 + }, + "options": { + "CLOCK": { + "ENABLED": 1, + "PRIMARYISLOCAL": 2, + "SECONDARY": 3, + "TERTIARY": 4, + "FORMATPRIMARY": 5, + "FORMATSECONDARY": 6, + "FORMATTERTIARY": 7, + "DATEFORMAT": 8 + }, + "LED": { + "FIRE": 1, + "THROTTLE": 2, + "A": 3, + "B": 4, + "D": 5, + "E": 6, + "T1": 7, + "T2": 8, + "T3": 9, + "POV": 10, + "CLUTCH": 11 + }, + "BRIGHTNESS": { + "MFD": 1, + "LED": 2 + }, + "MOUSE": { + "ENABLED": 1, + "SENSITIVITY": 2, + "SPEED": 3, + "REVERSESCROLL": 4, + "ISOMETRICMODE": 5, + "CURVEFACTOR": 6, + "DEADZONE": 7 + }, + "PROFILES": { + "DIRECTORY": 1, + "CLUTCHENABLED": 2, + "CLUTCHLATCHED": 3, + "KEYBOARDLAYOUT": 4 + } + } +} \ No newline at end of file diff --git a/daemon/constants.h b/daemon/constants.h index 68fd123..b769e3d 100644 --- a/daemon/constants.h +++ b/daemon/constants.h @@ -26,19 +26,6 @@ #define X52D_MAX_CLIENTS 63 -enum { - X52D_MOD_CONFIG, - X52D_MOD_CLOCK, - X52D_MOD_DEVICE, - X52D_MOD_IO, - X52D_MOD_LED, - X52D_MOD_MOUSE, - X52D_MOD_COMMAND, - X52D_MOD_CLIENT, - X52D_MOD_NOTIFY, - X52D_MOD_KEYBOARD_LAYOUT, - - X52D_MOD_MAX -}; +#include "module-map.h" // For module IDs #endif // !defined X52D_CONST_H diff --git a/daemon/meson.build b/daemon/meson.build index 26b0fe9..8499e26 100644 --- a/daemon/meson.build +++ b/daemon/meson.build @@ -1,4 +1,33 @@ # x52d (dep_config_h: Meson build-config.h; private API is daemon/config.h) +config_defs = custom_target('config-defs', + depend_files: ['x52d_map_config.py', 'x52d.conf'], + input: [ + 'x52d.conf', + 'config_registry.json' + ], + output: [ + 'config-defs.h', + 'config-defs.c', + 'config_defs.py' + ], + command: [ + python, meson.current_source_dir() / 'x52d_map_config.py', + '@INPUT0@', '@INPUT1@', + '@OUTPUT0@', '@OUTPUT1@', '@OUTPUT2@' + ]) + +module_defs = custom_target('module-defs', + depend_files: ['x52d_gen_module.py', 'module_defs.py'], + output: ['module-map.h', 'module-map.c'], + command: [python, meson.current_source_dir() / 'x52d_gen_module.py', + '@OUTPUT0@', '@OUTPUT1@']) + +slib_comm_defs = static_library('x52dcommdefs', + [config_defs[1], + module_defs[1], + 'name-id-map.c', + ]) + libx52dcomm_version = '1.0.0' libx52dcomm_sources = [ @@ -44,7 +73,7 @@ x52d_sources = [ dep_threads = dependency('threads') # Comm sources are compiled into x52d (same as Autotools); libx52dcomm is only for x52ctl. -x52d_linkwith = [lib_libx52, lib_vkm, lib_libx52io] +x52d_linkwith = [lib_libx52, lib_vkm, lib_libx52io, slib_comm_defs] x52d_deps = [dep_pinelog, dep_inih, dep_threads, dep_math, dep_intl, dep_config_h] x52d_cflags = [] diff --git a/daemon/module_defs.py b/daemon/module_defs.py new file mode 100644 index 0000000..de24e1e --- /dev/null +++ b/daemon/module_defs.py @@ -0,0 +1,28 @@ +"""Module name to identifier mapping""" + +from enum import Enum + +class Module(Enum): + """Module name to identifier""" + CONFIG = 0 + CLOCK = 1 + DEVICE = 2 + IO = 3 + LED = 4 + MOUSE = 5 + COMMAND = 6 + CLIENT = 7 + NOTIFY = 8 + KEYBOARD_LAYOUT = 9 + +class LogLevel(Enum): + """Map log level names to pinelog levels""" + # This is hard coded to the pinelog levels + NOTSET = -2 + NONE = -1 + FATAL = 0 + ERROR = 1 + WARNING = 2 + INFO = 3 + DEBUG = 4 + TRACE = 5 diff --git a/daemon/name-id-map.c b/daemon/name-id-map.c new file mode 100644 index 0000000..aeb3475 --- /dev/null +++ b/daemon/name-id-map.c @@ -0,0 +1,59 @@ +/* + * Name ID map - needed to map module/loglevel names to numeric v alues + * + * Copyright (C) 2026 Nirenjan Krishnan + * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + */ + +#include +#include + +#include "name-id-map.h" +#include "module-map.h" + +static int map_get_id(const struct name_id_map *map, const char *string) +{ + int i; + + for (i = 0; map[i].name != NULL; i++) { + if (strcasecmp(map[i].name, string) == 0) { + return map[i].id; + } + } + + // We've broken out of the loop, return the current ID + return map[i].id; +} + +static const char *map_get_name(const struct name_id_map *map, int id) +{ + int i; + + for (i = 0; map[i].name != NULL; i++) { + if (map[i].id == id) { + return map[i].name; + } + } + + return NULL; +} + +int lookup_module_by_name(const char *name) +{ + return map_get_id(module_map, name); +} + +const char * lookup_module_by_id(int id) +{ + return map_get_name(module_map, id); +} + +int lookup_level_by_name(const char *name) +{ + return map_get_id(loglevel_map, name); +} + +const char * lookup_level_by_id(int id) +{ + return map_get_name(loglevel_map, id); +} diff --git a/daemon/name-id-map.h b/daemon/name-id-map.h new file mode 100644 index 0000000..26edb15 --- /dev/null +++ b/daemon/name-id-map.h @@ -0,0 +1,19 @@ +/* + * Name ID map - needed to map module/loglevel names to numeric v alues + * + * Copyright (C) 2026 Nirenjan Krishnan + * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + */ + +#ifndef NAME_ID_MAP_H +#define NAME_ID_MAP_H + +struct name_id_map { + char *name; + int id; +}; + +extern const struct name_id_map module_map[]; +extern const struct name_id_map loglevel_map[]; + +#endif // !defined NAME_ID_MAP_H diff --git a/daemon/x52d_gen_module.py b/daemon/x52d_gen_module.py new file mode 100755 index 0000000..87da710 --- /dev/null +++ b/daemon/x52d_gen_module.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Generate the module name to map for use by the daemon""" + +import os.path +import sys + +import module_defs + +def main(): + + if len(sys.argv) != 3: + print("Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(1) + + with open(sys.argv[1], 'w', encoding='utf-8') as out_fd: + # Generate the header + print("// Autogenerated module/loglevel header - DO NOT EDIT\n", + file=out_fd) + + include_guard = os.path.basename(sys.argv[1]).replace('-', '_').replace('.', '_').upper() + print(f"#ifndef {include_guard}", file=out_fd) + print(f"#define {include_guard}\n", file=out_fd) + + for mod in module_defs.Module: + print(f"#define X52D_MOD_{mod.name} {mod.value}", file=out_fd) + + print(f"#define X52D_MOD_GLOBAL 0xFF", file=out_fd) + print(f"#define X52D_MOD_MAX {len(module_defs.Module)}\n", file=out_fd) + + print(f"int lookup_module_by_name(const char *name);", file=out_fd) + print(f"const char * lookup_module_by_id(int id);", file=out_fd) + print(f"int lookup_level_by_name(const char *name);", file=out_fd) + print(f"const char * lookup_level_by_id(int id);", file=out_fd) + + print(f"\n#endif // !defined {include_guard}", file=out_fd) + + with open(sys.argv[2], 'w', encoding='utf-8') as out_fd: + print("// Autogenerated module/loglevel tables - DO NOT EDIT\n", + file=out_fd) + + print('#include ', file=out_fd) + print('#include \n', file=out_fd) + + print(f'#include "{os.path.basename(sys.argv[1])}"', file=out_fd) + print('#include "name-id-map.h"\n', file=out_fd) + + print('const struct name_id_map module_map[] = {', file=out_fd) + for mod in module_defs.Module: + print(f' {{ "{mod.name.lower()}", {mod.value} }},', file=out_fd) + + print(' { NULL, INT_MAX }', file=out_fd) + print('};\n', file=out_fd) + + print('const struct name_id_map loglevel_map[] = {', file=out_fd) + for level in module_defs.LogLevel: + if level == module_defs.LogLevel.NOTSET: + level_name = 'default' + else: + level_name = level.name.lower() + + print(f' {{ "{level_name}", {level.value} }},', file=out_fd) + + print(' { NULL, INT_MAX }', file=out_fd) + + print('};\n', file=out_fd) + +if __name__ == '__main__': + main() diff --git a/daemon/x52d_map_config.py b/daemon/x52d_map_config.py new file mode 100755 index 0000000..a88340c --- /dev/null +++ b/daemon/x52d_map_config.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +"""Read the default configuration file, and create ID enums for sections + and options. +""" + +import argparse +import configparser +import json +import os.path + +from collections import defaultdict +from itertools import count +from pprint import pprint + +class ConfigToEnum: + """ConfigToEnum scans a configuration file, and dumps the secions and + options within a section as Python Enums""" + + REGISTRY_COMMENT = """The configuration registry is a historic record of +all configuration identifiers. Do NOT edit this file manually, or else, the +communication protocol may break.""" + + def __init__(self, cfg_file, config_ids): + """Initialize the object""" + self.config = configparser.ConfigParser(default_section=None, interpolation=None) + self.config.optionxform = str + self.config.read(cfg_file) + + self.registry_file = config_ids + + try: + with open(self.registry_file, encoding='utf-8') as regfd: + self.config_ids = json.load(regfd) + except Exception: + # On any error, ignore it and start with a clean slate + self.config_ids = {} + + self.sections = {} + self.options = {} + + def parse(self): + """Parse the config object and assign IDs""" + self._parse_sections() + for section in self.config.sections(): + self._parse_options(section) + + def _parse_sections(self): + """Assign IDs to each section""" + sections = {} + unassigned = [] + for section in self.config.sections(): + section = section.upper() + section_id = self.config_ids.get('sections', {}).get(section) + if section_id is None: + unassigned.append(section) + else: + sections[section] = section_id + + if not sections: + counter = count(1) + else: + counter = count(max(sections.values()) + 1) + + sections.update({k:v for k, v in zip(unassigned, counter)}) + + orig_sections = self.config_ids.get('sections', {}) + sections.update({k:v for k, v in orig_sections.items() if k not in sections}) + + self.sections = sections + + def _parse_options(self, section): + options = {} + unassigned = [] + for option in self.config.options(section): + option = option.upper() + section = section.upper() + option_id = self.config_ids.get('options', {}).get(section, {}).get(option) + if option_id is None: + unassigned.append(option) + else: + options[option] = option_id + + if not options: + counter = count(1) + else: + counter = count(max(options.values()) + 1) + + options.update({k:v for k, v in zip(unassigned, counter)}) + orig_options = self.config_ids.get('options', {}).get(section, {}) + + # Make sure that we have all the entries already + options.update({k:v for k, v in orig_options.items() if k not in options}) + + self.options[section] = options + + def save_registry(self): + """Save the generated registry""" + registry = { + "_comment": self.REGISTRY_COMMENT, + "sections": self.sections, + "options": self.options, + } + + with open(self.registry_file, 'w', encoding='utf-8') as regfd: + json.dump(registry, regfd, indent=4) + + def generate_c_definitions(self, output_header, output_source): + """Generate the C definitions""" + with open(output_header, 'w', encoding='utf-8') as out_fd: + include_guard = os.path.basename(output_header).replace('-', '_').replace('.', '_').upper() + + print("// Autogenerated config identifiers - DO NOT EDIT\n", file=out_fd) + print(f"#ifndef {include_guard}", file=out_fd) + print(f"#define {include_guard}", file=out_fd) + print(file=out_fd) + + max_sec_val = max(self.sections.values()) + 1 + max_opt_val_global = 0 + for section, value in self.sections.items(): + print(f"#define CFG_SECTION_{section} {value}", file=out_fd) + max_opt_val = max(self.options[section].values()) + 1 + max_opt_val_global = max(max_opt_val, max_opt_val_global) + + for option, value in self.options[section].items(): + print(f"#define CFG_OPTION_{section}_{option} {value}", file=out_fd) + + print(f"#define CFG_OPTION_{section}_MAX_OPTIONS {max_opt_val}\n", file=out_fd) + + print(f"#define CFG_SECTION_MAX {max_sec_val}\n", file=out_fd) + print(f"#define CFG_SECTION_MAX_OPT_VAL {max_opt_val_global}\n", file=out_fd) + + print("extern const char * section_names[CFG_SECTION_MAX];", file=out_fd) + print("extern const char * option_names[CFG_SECTION_MAX][CFG_SECTION_MAX_OPT_VAL];", file=out_fd) + + print(f"#endif // !defined {include_guard}", file=out_fd) + + with open(output_source, 'w', encoding='utf-8') as out_fd: + print("// Autogenerated config string table - DO NOT EDIT\n", file=out_fd) + print(f'#include "{os.path.basename(output_header)}"', file=out_fd) + + print("const char * section_names[CFG_SECTION_MAX] = {", file=out_fd) + for section, value in self.sections.items(): + print(f' [{value}] = "{section.lower()}",', file=out_fd) + print("};\n", file=out_fd) + + print("const char * options_names[CFG_SECTION_MAX][CFG_SECTION_MAX_OPT_VAL] = {", file=out_fd) + for section, value in self.sections.items(): + print(f' [{value}] =', '{', file=out_fd) + for option, value in self.options[section].items(): + print(f' [{value}] = "{option.lower()}",', file=out_fd) + print(' },', file=out_fd) + print("};\n", file=out_fd) + + + def generate_py_definitions(self, output_file): + """Generate the Python definitions""" + try: + out_fd = open(output_file, 'w', encoding='utf-8') + + print("'''Autogenerated config identifiers from x52d.conf'''", file=out_fd) + print("# DO NOT EDIT\n", file=out_fd) + print("from enum import Enum", file=out_fd) + + print("\nclass Section(Enum):", file=out_fd) + print(" '''Section identifiers'''", file=out_fd) + for section, value in self.sections.items(): + print(f" {section} = {value}", file=out_fd) + + for section in self.sections.keys(): + print(f"\nclass {section}(Enum):", file=out_fd) + print(f" '''Section {section} identifiers'''", file=out_fd) + for option, value in self.options[section].items(): + print(f" {option} = {value}", file=out_fd) + + finally: + out_fd.close() + + +def main(): + parser = argparse.ArgumentParser(description="Generate C enum and python enum for config") + parser.add_argument('input_file') + parser.add_argument('registry') + parser.add_argument('output_c_header') + parser.add_argument('output_c_strings') + parser.add_argument('output_py_defs') + + args = parser.parse_args() + + c2e = ConfigToEnum(args.input_file, args.registry) + c2e.parse() + c2e.save_registry() + + c2e.generate_c_definitions(args.output_c_header, args.output_c_strings) + c2e.generate_py_definitions(args.output_py_defs) + +if __name__ == '__main__': + main() diff --git a/po/libx52.pot b/po/libx52.pot index 504b65a..0a4f0cd 100644 --- a/po/libx52.pot +++ b/po/libx52.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.3.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2026-04-20 21:55-0700\n" +"POT-Creation-Date: 2026-04-22 09:02-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -285,89 +285,89 @@ msgstr "" msgid "Event @ %ld.%06ld: %s, value %d\n" msgstr "" -#: joytest/x52_test.c:97 +#: joytest/x52_test.c:99 msgid "Test brightness scale (~ 1m)" msgstr "" -#: joytest/x52_test.c:98 +#: joytest/x52_test.c:100 msgid "Test LED states (~ 45s)" msgstr "" -#: joytest/x52_test.c:99 +#: joytest/x52_test.c:101 msgid "Test MFD string display (~ 30s)" msgstr "" -#: joytest/x52_test.c:100 +#: joytest/x52_test.c:102 msgid "Test MFD displays all characters (~ 2m 15s)" msgstr "" -#: joytest/x52_test.c:101 +#: joytest/x52_test.c:103 msgid "Test the blink and shift commands (< 10s)" msgstr "" -#: joytest/x52_test.c:102 +#: joytest/x52_test.c:104 msgid "Test the clock commands (~1m)" msgstr "" -#: joytest/x52_test.c:126 +#: joytest/x52_test.c:128 msgid "" "x52test is a suite of tests to write to the X52 Pro device\n" "and test the extra functionality available in the LEDs and MFD\n" msgstr "" -#: joytest/x52_test.c:130 +#: joytest/x52_test.c:132 msgid "These tests take roughly 6 minutes to run" msgstr "" -#: joytest/x52_test.c:132 +#: joytest/x52_test.c:134 msgid "Press Enter to begin the tests, press Ctrl-C to abort anytime" msgstr "" -#: joytest/x52_test.c:138 +#: joytest/x52_test.c:140 #, c-format msgid "Unable to initialize X52 library: %s\n" msgstr "" -#: joytest/x52_test.c:153 -msgid "All tests completed successfully" -msgstr "" - #: joytest/x52_test.c:155 -#, c-format -msgid "Got error %s\n" +msgid "All tests completed successfully" msgstr "" #: joytest/x52_test.c:157 #, c-format +msgid "Got error %s\n" +msgstr "" + +#: joytest/x52_test.c:159 +#, c-format msgid "Received %s signal, quitting...\n" msgstr "" -#: joytest/x52_test.c:176 +#: joytest/x52_test.c:178 msgid "" "These are the available tests with a description and\n" "approximate runtime. Not specifying any tests will run\n" "all the tests\n" msgstr "" -#: joytest/x52_test.c:180 +#: joytest/x52_test.c:182 msgid "List of tests:" msgstr "" -#: joytest/x52_test.c:230 +#: joytest/x52_test.c:214 #, c-format msgid "" "Usage: %s [list of tests]\n" "\n" msgstr "" -#: joytest/x52_test.c:244 +#: joytest/x52_test.c:220 #, c-format msgid "" "Unrecognized test identifier: %s\n" "\n" msgstr "" -#: joytest/x52_test.c:257 +#: joytest/x52_test.c:231 msgid "Not running any tests" msgstr "" @@ -599,41 +599,41 @@ msgstr "" msgid "Shutting down X52 clock manager thread" msgstr "" -#: daemon/command.c:380 +#: daemon/command.c:310 #, c-format msgid "Error reading from client %d: %s" msgstr "" -#: daemon/command.c:391 +#: daemon/command.c:321 #, c-format msgid "Short write to client %d; expected %d bytes, wrote %d bytes" msgstr "" -#: daemon/command.c:416 +#: daemon/command.c:346 #, c-format msgid "Error %d during command loop: %s" msgstr "" -#: daemon/command.c:443 +#: daemon/command.c:373 #, c-format msgid "Error creating command socket: %s" msgstr "" -#: daemon/command.c:451 +#: daemon/command.c:381 #, c-format msgid "Error marking command socket as nonblocking: %s" msgstr "" -#: daemon/command.c:457 +#: daemon/command.c:387 #, c-format msgid "Error listening on command socket: %s" msgstr "" -#: daemon/command.c:461 +#: daemon/command.c:391 msgid "Starting command processing thread" msgstr "" -#: daemon/command.c:479 +#: daemon/command.c:409 msgid "Shutting down command processing thread" msgstr "" diff --git a/po/xx_PL.po b/po/xx_PL.po index d5fb0f5..fd920bf 100644 --- a/po/xx_PL.po +++ b/po/xx_PL.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.3.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2026-04-20 21:55-0700\n" +"POT-Creation-Date: 2026-04-22 09:02-0700\n" "PO-Revision-Date: 2026-04-04 12:00-0700\n" "Last-Translator: Nirenjan Krishnan \n" "Language-Team: Dummy Language for testing i18n\n" @@ -285,31 +285,31 @@ msgstr "Estingtay (interruptay otay exitay)\n" msgid "Event @ %ld.%06ld: %s, value %d\n" msgstr "Eventay @ %ld.%06ld: %s, aluevay %d\n" -#: joytest/x52_test.c:97 +#: joytest/x52_test.c:99 msgid "Test brightness scale (~ 1m)" msgstr "Esttay ightnessbray alescay (~ 1m)" -#: joytest/x52_test.c:98 +#: joytest/x52_test.c:100 msgid "Test LED states (~ 45s)" msgstr "Esstay EDLay atesstay (~ 45s)" -#: joytest/x52_test.c:99 +#: joytest/x52_test.c:101 msgid "Test MFD string display (~ 30s)" msgstr "Esttay MFDay ingstray isplayday (~ 30s)" -#: joytest/x52_test.c:100 +#: joytest/x52_test.c:102 msgid "Test MFD displays all characters (~ 2m 15s)" msgstr "Esttay MFDay isplaysday allay aracterschay (~ 2m 15s)" -#: joytest/x52_test.c:101 +#: joytest/x52_test.c:103 msgid "Test the blink and shift commands (< 10s)" msgstr "Esttay ethay inkblay anday iftshay ommandscay (< 10s)" -#: joytest/x52_test.c:102 +#: joytest/x52_test.c:104 msgid "Test the clock commands (~1m)" msgstr "Esttay ethay ockclay ommandscay (~1m)" -#: joytest/x52_test.c:126 +#: joytest/x52_test.c:128 msgid "" "x52test is a suite of tests to write to the X52 Pro device\n" "and test the extra functionality available in the LEDs and MFD\n" @@ -318,36 +318,36 @@ msgstr "" "X52 Pro eviceday anday esttay ethay extray unctionalityfay\n" "availableay inay ethay EDsLay anday FDMay\n" -#: joytest/x52_test.c:130 +#: joytest/x52_test.c:132 msgid "These tests take roughly 6 minutes to run" msgstr "Esethay eststay aketay oughlyray 6 inutesmay otay unray" -#: joytest/x52_test.c:132 +#: joytest/x52_test.c:134 msgid "Press Enter to begin the tests, press Ctrl-C to abort anytime" msgstr "" "Esspray Enteray otay eginbay ethay eststay, esspray Ctrl-C otay abortay " "anytimeay" -#: joytest/x52_test.c:138 +#: joytest/x52_test.c:140 #, c-format msgid "Unable to initialize X52 library: %s\n" msgstr "Unableay otay initializeay X52 ibrarylay: %s\n" -#: joytest/x52_test.c:153 +#: joytest/x52_test.c:155 msgid "All tests completed successfully" msgstr "Allay eststay ompletedcay uccessfullysay" -#: joytest/x52_test.c:155 +#: joytest/x52_test.c:157 #, c-format msgid "Got error %s\n" msgstr "Otgay erroray %s\n" -#: joytest/x52_test.c:157 +#: joytest/x52_test.c:159 #, c-format msgid "Received %s signal, quitting...\n" msgstr "Eceivedray %s ignalsay, uittingqay...\n" -#: joytest/x52_test.c:176 +#: joytest/x52_test.c:178 msgid "" "These are the available tests with a description and\n" "approximate runtime. Not specifying any tests will run\n" @@ -358,18 +358,18 @@ msgstr "" "ecifyingspay anyay eststay illway unray allay ethay\n" "eststay\n" -#: joytest/x52_test.c:180 +#: joytest/x52_test.c:182 msgid "List of tests:" msgstr "Istlay ofay eststay:" -#: joytest/x52_test.c:230 +#: joytest/x52_test.c:214 #, c-format msgid "" "Usage: %s [list of tests]\n" "\n" msgstr "Usageay: %s [istlay ofay eststay]\n" -#: joytest/x52_test.c:244 +#: joytest/x52_test.c:220 #, c-format msgid "" "Unrecognized test identifier: %s\n" @@ -378,7 +378,7 @@ msgstr "" "Unrecognizeday esttay identifieray: %s\n" "\n" -#: joytest/x52_test.c:257 +#: joytest/x52_test.c:231 msgid "Not running any tests" msgstr "Otnay unningray anyay eststay" @@ -645,42 +645,42 @@ msgstr "Erroray %d initializingay ockclay eadthray: %s" msgid "Shutting down X52 clock manager thread" msgstr "Uttingshay ownday X52 ockclay anagermay eadthray" -#: daemon/command.c:380 +#: daemon/command.c:310 #, c-format msgid "Error reading from client %d: %s" msgstr "Erroray eadingray omfray ientclay %d: %s" -#: daemon/command.c:391 +#: daemon/command.c:321 #, c-format msgid "Short write to client %d; expected %d bytes, wrote %d bytes" msgstr "" "Ortshay itewray otay ientclay %d; expecteday %d ytesbay, otewray %d ytesbay" -#: daemon/command.c:416 +#: daemon/command.c:346 #, c-format msgid "Error %d during command loop: %s" msgstr "Erroray %d uringday ommandcay ooplay: %s" -#: daemon/command.c:443 +#: daemon/command.c:373 #, c-format msgid "Error creating command socket: %s" msgstr "Erroray eatingcray ommandcay ocketsay: %s" -#: daemon/command.c:451 +#: daemon/command.c:381 #, c-format msgid "Error marking command socket as nonblocking: %s" msgstr "Erroray arkingmay ommandcay ocketsay asay onblockingnay: %s" -#: daemon/command.c:457 +#: daemon/command.c:387 #, c-format msgid "Error listening on command socket: %s" msgstr "Erroray isteninglay onay ommandcay ocketsay: %s" -#: daemon/command.c:461 +#: daemon/command.c:391 msgid "Starting command processing thread" msgstr "Artingstay ommandcay ocessingpray eadthray" -#: daemon/command.c:479 +#: daemon/command.c:409 msgid "Shutting down command processing thread" msgstr "Uttingshay ownday ommandcay ocessingpray eadthray"