aboutsummaryrefslogtreecommitdiff
path: root/lib/libusb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libusb')
-rw-r--r--lib/libusb/libusb.315
-rw-r--r--lib/libusb/libusb.h3
-rw-r--r--lib/libusb/libusb10.c126
-rw-r--r--lib/libusb/libusb10.h6
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);