diff options
Diffstat (limited to 'lib/libusb')
-rw-r--r-- | lib/libusb/libusb.3 | 15 | ||||
-rw-r--r-- | lib/libusb/libusb.h | 3 | ||||
-rw-r--r-- | lib/libusb/libusb10.c | 126 | ||||
-rw-r--r-- | lib/libusb/libusb10.h | 6 |
4 files changed, 117 insertions, 33 deletions
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 index a9a99f307a86..74b85d4aa17e 100644 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 12, 2025 +.Dd June 13, 2025 .Dt LIBUSB 3 .Os .Sh NAME @@ -106,6 +106,19 @@ Get the ASCII representation of the error given by the argument. This function does not return NULL. .Pp +.Ft int +.Fn libusb_setlocale "const char *locale" +Set locale for the error message when using +.Fn libusb_strerror +to +.Ft locale . +Note other +.Nm +implementations only support the first two bytes, that means +.Ql en-US +is equivalent to +.Ql en-CA . +.Pp .Ft const char * .Fn libusb_error_name "int code" Get the ASCII representation of the error enum given by the diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index 17d341d1b91c..6fb1c19fad13 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -210,6 +210,8 @@ enum libusb_error { LIBUSB_ERROR_OTHER = -99, }; +#define LIBUSB_ERROR_COUNT 14 + enum libusb_speed { LIBUSB_SPEED_UNKNOWN = 0, LIBUSB_SPEED_LOW = 1, @@ -475,6 +477,7 @@ int libusb_init(libusb_context ** context); int libusb_init_context(libusb_context **, const struct libusb_init_option [], int num_options); void libusb_exit(struct libusb_context *ctx); int libusb_has_capability(uint32_t capability); +int libusb_setlocale(const char *locale); /* Device handling and enumeration */ diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 173f51aa88b3..6f1ca877fc28 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -4,6 +4,7 @@ * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. * Copyright (c) 2009-2023 Hans Petter Selasky * Copyright (c) 2024 Aymeric Wibo + * Copyright (c) 2025 ShengYi Hung * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +32,7 @@ #include LIBUSB_GLOBAL_INCLUDE_FILE #else #include <assert.h> +#include <ctype.h> #include <errno.h> #include <poll.h> #include <pthread.h> @@ -84,6 +86,52 @@ static const struct libusb_version libusb_version = { .describe = "https://www.freebsd.org" }; +static const struct libusb_language_context libusb_language_ctx[] = { + { + .lang_name = "en", + .err_strs = { + [-LIBUSB_SUCCESS] = "Success", + [-LIBUSB_ERROR_IO] = "I/O error", + [-LIBUSB_ERROR_INVALID_PARAM] = "Invalid parameter", + [-LIBUSB_ERROR_ACCESS] = "Permissions error", + [-LIBUSB_ERROR_NO_DEVICE] = "No device", + [-LIBUSB_ERROR_NOT_FOUND] = "Not found", + [-LIBUSB_ERROR_BUSY] = "Device busy", + [-LIBUSB_ERROR_TIMEOUT] = "Timeout", + [-LIBUSB_ERROR_OVERFLOW] = "Overflow", + [-LIBUSB_ERROR_PIPE] = "Pipe error", + [-LIBUSB_ERROR_INTERRUPTED] = "Interrupted", + [-LIBUSB_ERROR_NO_MEM] = "Out of memory", + [-LIBUSB_ERROR_NOT_SUPPORTED] ="Not supported", + [LIBUSB_ERROR_COUNT - 1] = "Other error", + [LIBUSB_ERROR_COUNT] = "Unknown error", + } + }, + { + .lang_name = "zh", + .err_strs = { + [-LIBUSB_SUCCESS] = "成功", + [-LIBUSB_ERROR_IO] = "I/O 錯誤", + [-LIBUSB_ERROR_INVALID_PARAM] = "不合法的參數", + [-LIBUSB_ERROR_ACCESS] = "權限錯誤", + [-LIBUSB_ERROR_NO_DEVICE] = "裝置不存在", + [-LIBUSB_ERROR_NOT_FOUND] = "不存在", + [-LIBUSB_ERROR_BUSY] = "裝置忙碌中", + [-LIBUSB_ERROR_TIMEOUT] = "逾時", + [-LIBUSB_ERROR_OVERFLOW] = "溢位", + [-LIBUSB_ERROR_PIPE] = "管道錯誤", + [-LIBUSB_ERROR_INTERRUPTED] = "被中斷", + [-LIBUSB_ERROR_NO_MEM] = "記憶體不足", + [-LIBUSB_ERROR_NOT_SUPPORTED] ="不支援", + [LIBUSB_ERROR_COUNT - 1] = "其他錯誤", + [LIBUSB_ERROR_COUNT] = "未知錯誤", + } + }, +}; + +static const struct libusb_language_context *default_language_context = + &libusb_language_ctx[0]; + const struct libusb_version * libusb_get_version(void) { @@ -1728,38 +1776,26 @@ libusb_le16_to_cpu(uint16_t x) const char * libusb_strerror(int code) { - switch (code) { - case LIBUSB_SUCCESS: - return ("Success"); - case LIBUSB_ERROR_IO: - return ("I/O error"); - case LIBUSB_ERROR_INVALID_PARAM: - return ("Invalid parameter"); - case LIBUSB_ERROR_ACCESS: - return ("Permissions error"); - case LIBUSB_ERROR_NO_DEVICE: - return ("No device"); - case LIBUSB_ERROR_NOT_FOUND: - return ("Not found"); - case LIBUSB_ERROR_BUSY: - return ("Device busy"); - case LIBUSB_ERROR_TIMEOUT: - return ("Timeout"); - case LIBUSB_ERROR_OVERFLOW: - return ("Overflow"); - case LIBUSB_ERROR_PIPE: - return ("Pipe error"); - case LIBUSB_ERROR_INTERRUPTED: - return ("Interrupted"); - case LIBUSB_ERROR_NO_MEM: - return ("Out of memory"); - case LIBUSB_ERROR_NOT_SUPPORTED: - return ("Not supported"); - case LIBUSB_ERROR_OTHER: - return ("Other error"); - default: - return ("Unknown error"); - } + int entry = -code; + + if (code == LIBUSB_ERROR_OTHER) + entry = LIBUSB_ERROR_COUNT - 1; + /* + * The libusb upstream considers all code out of range a + * LIBUSB_ERROR_OTHER. In FreeBSD, it is a special unknown error. We + * preserve the FreeBSD implementation as I think it make sense. + */ + if (entry < 0 || entry >= LIBUSB_ERROR_COUNT) + entry = LIBUSB_ERROR_COUNT; + + /* + * Fall back to English one as the translation may be unimplemented + * when adding new error code. + */ + if (default_language_context->err_strs[entry] == NULL) + return (libusb_language_ctx[0].err_strs[entry]); + + return (default_language_context->err_strs[entry]); } const char * @@ -1842,3 +1878,29 @@ libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level, va_end(args); } + +/* + * Upstream code actually recognizes the first two characters to identify a + * language. We do so to provide API compatibility with setlocale. + */ +int +libusb_setlocale(const char *locale) +{ + size_t idx; + const char *lang; + + if (locale == NULL || strlen(locale) < 2 || + (locale[2] != '\0' && strchr("-_.", locale[2]) == NULL)) + return (LIBUSB_ERROR_INVALID_PARAM); + + for (idx = 0; idx < nitems(libusb_language_ctx); ++idx) { + lang = libusb_language_ctx[idx].lang_name; + if (tolower(locale[0]) == lang[0] && + tolower(locale[1]) == lang[1]) { + default_language_context = &libusb_language_ctx[idx]; + return (LIBUSB_SUCCESS); + } + } + + return (LIBUSB_ERROR_INVALID_PARAM); +} diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h index 9ad08edf075b..eced364ef857 100644 --- a/lib/libusb/libusb10.h +++ b/lib/libusb/libusb10.h @@ -139,6 +139,12 @@ struct libusb_device { struct libusb20_device *os_priv; }; +struct libusb_language_context { + const char *lang_name; + /* All error Plus 1 UNKNOWN */ + const char *err_strs[LIBUSB_ERROR_COUNT + 1]; +}; + extern struct libusb_context *usbi_default_context; void libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd, struct libusb20_device *pdev, int fd, short events); |