This patch adds the much requested libusb_strerror() function, taking into
account all issues people raised wrt previous attempts.

Criteria / Decisions underlying this implementation:
-Must support translated messages
-Must not use gettext as that does not work well in combination with Windows
 (when building with Visual C, or for Windows CE)
-API compatible with FreeBSD and various patched libusb-s floating around
-KISS:
 -Do not add any (other) library dependencies
 -Do not try to deal with message encodings (iconv), simply always return UTF-8
  making encoding the problem of the application using libusb_strerror.
 -Defaults to English, so apps which don't want translated messages,
  don't need to do anything special
 -Defaults to English (with pure ASCII messages), so apps which don't
  call libusb_setlocale() don't need to worry about encoding

This patch includes a Dutch tranlation for the messages to show how further
languages can be added in a simple manner.

Signed-off-by: Hans de Goede <hdego...@redhat.com>
---
 libusb/Makefile.am    |   5 +-
 libusb/libusb-1.0.def |   4 +
 libusb/libusb.h       |  11 ++-
 libusb/strerror.c     | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libusb/version_nano.h |   2 +-
 5 files changed, 220 insertions(+), 7 deletions(-)
 create mode 100644 libusb/strerror.c

diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index cd6db9c..7f9c1f9 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -59,9 +59,10 @@ endif
 
 libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
 libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
-libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC) \
+libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
        os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
-       hotplug.h hotplug.c $(THREADS_SRC) os/poll_posix.h os/poll_windows.h
+       hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
+       os/poll_posix.h os/poll_windows.h
 
 hdrdir = $(includedir)/libusb-1.0
 hdr_HEADERS = libusb.h
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index 7166d47..9d1dd80 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -134,8 +134,12 @@ EXPORTS
   libusb_set_debug@8 = libusb_set_debug
   libusb_set_interface_alt_setting
   libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
+  libusb_set_locale
+  libusb_set_locale@4 = libusb_set_locale
   libusb_set_pollfd_notifiers
   libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
+  libusb_strerror
+  libusb_strerror@4 = libusb_strerror
   libusb_submit_transfer
   libusb_submit_transfer@4 = libusb_submit_transfer
   libusb_try_lock_events
diff --git a/libusb/libusb.h b/libusb/libusb.h
index d733c46..311d7f2 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -1044,8 +1044,9 @@ enum libusb_bos_type {
 /** \ingroup misc
  * Error codes. Most libusbx functions return 0 on success or one of these
  * codes on failure.
- * You can call \ref libusb_error_name() to retrieve a string representation
- * of an error code.
+ * You can call libusb_error_name() to retrieve a string representation of an
+ * error code or libusb_strerror() to get an end-user suitable description of
+ * an error code.
  */
 enum libusb_error {
        /** Success (no error) */
@@ -1087,8 +1088,8 @@ enum libusb_error {
        /** Operation not supported or unimplemented on this platform */
        LIBUSB_ERROR_NOT_SUPPORTED = -12,
 
-       /* NB! Remember to update libusb_error_name()
-          when adding new error codes here. */
+       /* NB! Remember to update libusb_error_name() and
+          libusb_strerror() when adding new error codes here. */
 
        /** Other error */
        LIBUSB_ERROR_OTHER = -99,
@@ -1299,6 +1300,8 @@ void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, 
int level);
 const struct libusb_version * LIBUSB_CALL libusb_get_version(void);
 int LIBUSB_CALL libusb_has_capability(uint32_t capability);
 const char * LIBUSB_CALL libusb_error_name(int errcode);
+int LIBUSB_CALL libusb_setlocale(const char *locale);
+const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode);
 
 ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx,
        libusb_device ***list);
diff --git a/libusb/strerror.c b/libusb/strerror.c
new file mode 100644
index 0000000..bea75a3
--- /dev/null
+++ b/libusb/strerror.c
@@ -0,0 +1,205 @@
+/*
+ * libusb strerror code
+ * Copyright © 2013 Hans de Goede <hdego...@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libusb.h"
+#include "libusbi.h"
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+enum libusb_locale_enum {
+       LANG_EN,
+       LANG_NL,
+};
+#endif
+
+static int libusb_locale = LANG_EN;
+
+/** \ingroup misc
+ * Set the language, and only the language, not the encoding! used for
+ * translatable libusb messages.
+ *
+ * This takes a locale string in the default setlocale format:
+ * lang[_country_region][.codeset]. Only the lang part of the string is used,
+ * and only 2 letter ISO 639-1 codes are accepted, ie "en". The optional
+ * country_regio and codeset parts are ignored. This means that functions
+ * which return translatable strings will NOT honor the specified encoding.
+ * If lang is en, then all translatable strings will be pure ASCII, for all
+ * other languages they will be encoded as UTF-8 strings!
+ *
+ * If libusb_setlocale() is not called, all messages will be in English.
+ *
+ * The following functions return translatable strings: libusb_strerror().
+ * Note that the libusb log messages controlled through libusb_set_debug()
+ * are not translated, they are always in English.
+ *
+ * For POSIX UTF-8 environments if you want libusb to follow the standard
+ * locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)),
+ * after your app has done its locale setup.
+ *
+ * \param locale locale-string in the form of lang[_country_region][.codeset]
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported
+ * \returns a LIBUSB_ERROR code on other errors
+ */
+int API_EXPORTED libusb_setlocale(const char *locale)
+{
+       const char * const iso639[] = {
+               /* Note the order here MUST match the libusb_locale_enum */
+               "en", /* LANG_EN */
+               "nl", /* LANG_NL */
+               NULL
+       };
+       char lang[3] = { 0, };
+       int i;
+
+       for (i = 0;
+            i < 3 && locale[i] && locale[i] != '_' && locale[i] != '.';
+            i++)
+               lang[i] = locale[i];
+
+       if (lang[2] != 0) {
+               usbi_warn(NULL, "Unrecognized locale format: %s", locale);
+               return LIBUSB_ERROR_INVALID_PARAM;
+       }
+
+       for (i = 0; iso639[i]; i++) {
+               if (strcmp(lang, iso639[i]) == 0)
+                       break;
+       }
+       if (!iso639[i]) {
+               usbi_warn(NULL, "Unsupported language: %s", lang);
+               return LIBUSB_ERROR_NOT_FOUND;
+       }
+
+       libusb_locale = i;
+
+       return LIBUSB_SUCCESS;
+}
+
+static const char *libusb_strerror_en(enum libusb_error errcode)
+{
+       switch (errcode) {
+       case LIBUSB_SUCCESS:
+               return "Success";
+       case LIBUSB_ERROR_IO:
+               return "Input/output error";
+       case LIBUSB_ERROR_INVALID_PARAM:
+               return "Invalid parameter";
+       case LIBUSB_ERROR_ACCESS:
+               return "Access denied (insufficient permissions)";
+       case LIBUSB_ERROR_NO_DEVICE:
+               return "No such device (it may have been disconnected)";
+       case LIBUSB_ERROR_NOT_FOUND:
+               return "Entity not found";
+       case LIBUSB_ERROR_BUSY:
+               return "Resource busy";
+       case LIBUSB_ERROR_TIMEOUT:
+               return "Operation timed out";
+       case LIBUSB_ERROR_OVERFLOW:
+               return "Overflow";
+       case LIBUSB_ERROR_PIPE:
+               return "Pipe error";
+       case LIBUSB_ERROR_INTERRUPTED:
+               return "System call interrupted (perhaps due to signal)";
+       case LIBUSB_ERROR_NO_MEM:
+               return "Insufficient memory";
+       case LIBUSB_ERROR_NOT_SUPPORTED:
+               return "Operation not supported or unimplemented on this 
platform";
+       case LIBUSB_ERROR_OTHER:
+               return "Other error";
+       default:
+               return "Unknown error";
+       }
+}
+
+static const char *libusb_strerror_nl(enum libusb_error errcode)
+{
+       switch (errcode) {
+       case LIBUSB_SUCCESS:
+               return "Gelukt";
+       case LIBUSB_ERROR_IO:
+               return "Invoer-/uitvoerfout";
+       case LIBUSB_ERROR_INVALID_PARAM:
+               return "Ongeldig argument";
+       case LIBUSB_ERROR_ACCESS:
+               return "Toegang geweigerd (onvoldoende toegangsrechten)";
+       case LIBUSB_ERROR_NO_DEVICE:
+               return "Apparaat bestaat niet (verbinding met apparaat 
verbroken?)";
+       case LIBUSB_ERROR_NOT_FOUND:
+               return "Niet gevonden";
+       case LIBUSB_ERROR_BUSY:
+               return "Apparaat of hulpbron is bezig";
+       case LIBUSB_ERROR_TIMEOUT:
+               return "Bewerking verlopen";
+       case LIBUSB_ERROR_OVERFLOW:
+               return "Waarde is te groot";
+       case LIBUSB_ERROR_PIPE:
+               return "Gebroken pijp";
+       case LIBUSB_ERROR_INTERRUPTED:
+               return "Onderbroken systeemaanroep";
+       case LIBUSB_ERROR_NO_MEM:
+               return "Onvoldoende geheugen beschikbaar";
+       case LIBUSB_ERROR_NOT_SUPPORTED:
+               return "Bewerking wordt niet ondersteund";
+       case LIBUSB_ERROR_OTHER:
+               return "Andere fout";
+       default:
+               return NULL; /* fall back to English translation */
+       }
+}
+
+/** \ingroup misc
+ * Returns a constant string with a short description of the given error code,
+ * this description is intended for displaying to the end user and will be in
+ * the language set by libusb_setlocale().
+ *
+ * The returned string is encoded in ASCII for English messages (the default
+ * if libusb_setlocale() is not called). For all other languages it is
+ * encoded in UTF-8!
+ *
+ * The messages always start with a capital letter and end without any dot.
+ * The caller must not free() the returned string.
+ *
+ * \param errcode the error code whose description is desired
+ * \returns a short description of the error code in UTF-8 encoding
+ */
+DEFAULT_VISIBILITY const char* libusb_strerror(enum libusb_error errcode)
+{
+       const char *msg = NULL;
+
+       switch (libusb_locale) {
+               case LANG_EN:
+                       msg = libusb_strerror_en(errcode);
+                       break;
+               case LANG_NL:
+                       msg = libusb_strerror_nl(errcode);
+                       break;
+       }
+
+       if (!msg) {
+               /* No translated msg for this errcode, fall back to English */
+               msg = libusb_strerror_en(errcode);
+       }
+
+       return msg;
+}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 2804c7d..69bc4ae 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10728
+#define LIBUSB_NANO 10730
-- 
1.8.2.1


------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to