Add strerror and tests

virtual-keyboard-mouse
nirenjan 2026-03-27 20:56:00 -07:00
parent 8418f9f0ad
commit f9b58bc19d
7 changed files with 197 additions and 10 deletions

View File

@ -4,6 +4,8 @@ libx52/x52_stringify.c
libx52io/io_strings.c libx52io/io_strings.c
vkm/vkm_common.c
evtest/ev_test.c evtest/ev_test.c
joytest/x52_test.c joytest/x52_test.c

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: libx52 0.3.3\n" "Project-Id-Version: libx52 0.3.3\n"
"Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n"
"POT-Creation-Date: 2026-03-27 08:32-0700\n" "POT-Creation-Date: 2026-03-27 20:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: libx52/x52_strerror.c:23 libx52io/io_strings.c:101 #: libx52/x52_strerror.c:23 libx52io/io_strings.c:101 vkm/vkm_common.c:25
msgid "Success" msgid "Success"
msgstr "" msgstr ""
@ -29,7 +29,7 @@ msgstr ""
msgid "Insufficient memory" msgid "Insufficient memory"
msgstr "" msgstr ""
#: libx52/x52_strerror.c:26 #: libx52/x52_strerror.c:26 vkm/vkm_common.c:29
msgid "Invalid parameter" msgid "Invalid parameter"
msgstr "" msgstr ""
@ -85,7 +85,7 @@ msgstr ""
msgid "System call interrupted" msgid "System call interrupted"
msgstr "" msgstr ""
#: libx52/x52_strerror.c:66 libx52io/io_strings.c:125 #: libx52/x52_strerror.c:66 libx52io/io_strings.c:125 vkm/vkm_common.c:52
#, c-format #, c-format
msgid "Unknown error %d" msgid "Unknown error %d"
msgstr "" msgstr ""
@ -233,6 +233,34 @@ msgstr ""
msgid "Read timeout" msgid "Read timeout"
msgstr "" msgstr ""
#: vkm/vkm_common.c:26
msgid "Unknown error"
msgstr ""
#: vkm/vkm_common.c:27
msgid "Not ready"
msgstr ""
#: vkm/vkm_common.c:28
msgid "Out of memory"
msgstr ""
#: vkm/vkm_common.c:30
msgid "Not supported"
msgstr ""
#: vkm/vkm_common.c:31
msgid "Virtual device failure"
msgstr ""
#: vkm/vkm_common.c:32
msgid "Unable to write event"
msgstr ""
#: vkm/vkm_common.c:33
msgid "No state change"
msgstr ""
#: evtest/ev_test.c:110 #: evtest/ev_test.c:110
#, c-format #, c-format
msgid "Device ID: vendor 0x%04x product 0x%04x version 0x%04x\n" msgid "Device ID: vendor 0x%04x product 0x%04x version 0x%04x\n"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: libx52 0.2.3\n" "Project-Id-Version: libx52 0.2.3\n"
"Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n"
"POT-Creation-Date: 2026-03-27 08:32-0700\n" "POT-Creation-Date: 2026-03-27 20:52-0700\n"
"PO-Revision-Date: 2026-03-27 08:33-0700\n" "PO-Revision-Date: 2026-03-27 08:33-0700\n"
"Last-Translator: Nirenjan Krishnan <nirenjan@gmail.com>\n" "Last-Translator: Nirenjan Krishnan <nirenjan@gmail.com>\n"
"Language-Team: Dummy Language for testing i18n\n" "Language-Team: Dummy Language for testing i18n\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.4.2\n" "X-Generator: Poedit 3.4.2\n"
#: libx52/x52_strerror.c:23 libx52io/io_strings.c:101 #: libx52/x52_strerror.c:23 libx52io/io_strings.c:101 vkm/vkm_common.c:25
msgid "Success" msgid "Success"
msgstr "Uccesssay" msgstr "Uccesssay"
@ -29,7 +29,7 @@ msgstr "Initializationay ailurefay"
msgid "Insufficient memory" msgid "Insufficient memory"
msgstr "Insufficientay emorymay" msgstr "Insufficientay emorymay"
#: libx52/x52_strerror.c:26 #: libx52/x52_strerror.c:26 vkm/vkm_common.c:29
msgid "Invalid parameter" msgid "Invalid parameter"
msgstr "Invaliday arameterpay" msgstr "Invaliday arameterpay"
@ -85,7 +85,7 @@ msgstr "Ipepay erroray"
msgid "System call interrupted" msgid "System call interrupted"
msgstr "Ystemsay allcay interrupteday" msgstr "Ystemsay allcay interrupteday"
#: libx52/x52_strerror.c:66 libx52io/io_strings.c:125 #: libx52/x52_strerror.c:66 libx52io/io_strings.c:125 vkm/vkm_common.c:52
#, c-format #, c-format
msgid "Unknown error %d" msgid "Unknown error %d"
msgstr "Unknownay erroray %d" msgstr "Unknownay erroray %d"
@ -233,6 +233,36 @@ msgstr "I/O erroray"
msgid "Read timeout" msgid "Read timeout"
msgstr "Eadray imeouttay" msgstr "Eadray imeouttay"
#: vkm/vkm_common.c:26
#, fuzzy
msgid "Unknown error"
msgstr "Unknownay erroray %d"
#: vkm/vkm_common.c:27
msgid "Not ready"
msgstr ""
#: vkm/vkm_common.c:28
msgid "Out of memory"
msgstr ""
#: vkm/vkm_common.c:30
#, fuzzy
msgid "Not supported"
msgstr "Operationay otnay upportedsay"
#: vkm/vkm_common.c:31
msgid "Virtual device failure"
msgstr ""
#: vkm/vkm_common.c:32
msgid "Unable to write event"
msgstr ""
#: vkm/vkm_common.c:33
msgid "No state change"
msgstr ""
#: evtest/ev_test.c:110 #: evtest/ev_test.c:110
#, c-format #, c-format
msgid "Device ID: vendor 0x%04x product 0x%04x version 0x%04x\n" msgid "Device ID: vendor 0x%04x product 0x%04x version 0x%04x\n"

View File

@ -25,9 +25,19 @@ endif
lib_vkm = library('vkm', vkm_files + vkm_platform_files, lib_vkm = library('vkm', vkm_files + vkm_platform_files,
install: true, install: true,
version: vkm_version, version: vkm_version,
dependencies: [vkm_dep], dependencies: [vkm_dep, dep_intl],
include_directories: [includes]) include_directories: [includes])
vkm_strerror_test = executable('vkm-strerror-test',
'test_strerror.c',
'vkm_common.c',
build_by_default: false,
dependencies: [dep_cmocka, dep_intl],
include_directories: [includes],
)
test('vkm-strerror', vkm_strerror_test, protocol: 'tap')
if host_machine.system() == 'linux' and dep_evdev.found() if host_machine.system() == 'linux' and dep_evdev.found()
dep_evdev_headers = dep_evdev.partial_dependency(compile_args: true, link_args: false) dep_evdev_headers = dep_evdev.partial_dependency(compile_args: true, link_args: false)
vkm_linux_evdev_test = executable('vkm_linux_evdev_test', vkm_linux_evdev_test = executable('vkm_linux_evdev_test',
@ -37,7 +47,7 @@ if host_machine.system() == 'linux' and dep_evdev.found()
'vkm_common.c', 'vkm_common.c',
), ),
include_directories: [includes], include_directories: [includes],
dependencies: [dep_cmocka, dep_evdev_headers], dependencies: [dep_cmocka, dep_evdev_headers, dep_intl],
) )
test('vkm_linux_evdev', vkm_linux_evdev_test) test('vkm_linux_evdev', vkm_linux_evdev_test)
endif endif

View File

@ -0,0 +1,57 @@
/*
* VKM strerror unit tests
*
* Copyright (C) 2026 Nirenjan Krishnan (nirenjan@nirenjan.org)
*
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdio.h>
#include <string.h>
#include "vkm.h"
static void test_strerror(void **state)
{
(void)state;
static const char *error_map[VKM_ERROR_MAX] = {
[VKM_SUCCESS] = "Success",
[VKM_ERROR_UNKNOWN] = "Unknown error",
[VKM_ERROR_NOT_READY] = "Not ready",
[VKM_ERROR_OUT_OF_MEMORY] = "Out of memory",
[VKM_ERROR_INVALID_PARAM] = "Invalid parameter",
[VKM_ERROR_NOT_SUPPORTED] = "Not supported",
[VKM_ERROR_DEV_FAILURE] = "Virtual device failure",
[VKM_ERROR_EVENT] = "Unable to write event",
[VKM_ERROR_NO_CHANGE] = "No state change",
};
static const char *unknown_fmt = "Unknown error %d";
char expected[256];
for (int i = -1; i <= (int)VKM_ERROR_MAX + 1; i++) {
if (i < 0 || i >= (int)VKM_ERROR_MAX || error_map[i] == NULL) {
snprintf(expected, sizeof(expected), unknown_fmt, i);
} else {
strncpy(expected, error_map[i], sizeof(expected));
}
assert_string_equal(expected, vkm_strerror(i));
}
}
static const struct CMUnitTest tests[] = {
cmocka_unit_test(test_strerror),
};
int main(void)
{
cmocka_set_message_output(CM_OUTPUT_TAP);
cmocka_run_group_tests(tests, NULL, NULL);
return 0;
}

View File

@ -96,6 +96,22 @@ typedef enum {
VKM_ERROR_MAX, VKM_ERROR_MAX,
} vkm_error_code; } vkm_error_code;
/**
* @brief Return a short description for a \ref vkm_result / \ref vkm_error_code value
*
* The returned pointer refers to static storage and must not be freed. For
* unrecognized codes, the same static buffer may be overwritten by a later call.
*
* When native language support (NLS) is enabled at build time, these messages
* are translated like \ref libx52_strerror. Bind the \c libx52 text domain and
* set \c LC_MESSAGES as for other libx52 components.
*
* @param[in] code Value returned from a VKM API function
*
* @returns Pointer to a NUL-terminated description string
*/
const char *vkm_strerror(vkm_result code);
/** /**
* @brief Option list * @brief Option list
*/ */

View File

@ -6,10 +6,54 @@
* SPDX-LicenseIdentifier: GPL-2.0-only WITH Classpath-exception-2.0 * SPDX-LicenseIdentifier: GPL-2.0-only WITH Classpath-exception-2.0
*/ */
#include "config.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "gettext.h"
#include "vkm-internal.h" #include "vkm-internal.h"
#define N_(str) gettext_noop(str)
#define _(str) dgettext(PACKAGE, str)
/* Error buffer used for building custom error strings */
static char error_buffer[256];
/* List of error strings (indices must match \ref vkm_error_code) */
static const char *error_string[] = {
N_("Success"),
N_("Unknown error"),
N_("Not ready"),
N_("Out of memory"),
N_("Invalid parameter"),
N_("Not supported"),
N_("Virtual device failure"),
N_("Unable to write event"),
N_("No state change"),
};
const char *vkm_strerror(vkm_result code)
{
switch ((vkm_error_code)code) {
case VKM_SUCCESS:
case VKM_ERROR_UNKNOWN:
case VKM_ERROR_NOT_READY:
case VKM_ERROR_OUT_OF_MEMORY:
case VKM_ERROR_INVALID_PARAM:
case VKM_ERROR_NOT_SUPPORTED:
case VKM_ERROR_DEV_FAILURE:
case VKM_ERROR_EVENT:
case VKM_ERROR_NO_CHANGE:
return _(error_string[code]);
default:
snprintf(error_buffer, sizeof(error_buffer),
_("Unknown error %d"), (int)code);
return error_buffer;
}
}
vkm_button_state _vkm_get_mouse_button_state(struct vkm_mouse_button_state *state, vkm_mouse_button button) vkm_button_state _vkm_get_mouse_button_state(struct vkm_mouse_button_state *state, vkm_mouse_button button)
{ {
if (state == NULL) { if (state == NULL) {