On 2013.06.08 19:22, Hans de Goede wrote:
a dash or a dot, ie accept "nl.UTF-8".

Good point.

Ok, so lets modify your proposal with an INVALAD_PARAM check then, and
move forward with your proposal.

OK. If I understand the rest of your message properly, you don't want the function with the switch for the errcode to index conversion, right? Coz if we go with that, we will then need to update 3 things when adding a new error code:
- LIBUSB_ERROR_COUNT
- New message strings for each locale
- A new case for the errcode to index switch

While the first two are hard to miss IMO, the 3rd, which would only come from that extra function call, not as much. Also, I think the whole switch just to return mostly increasing integers would look kind of silly, and it'd make libusb_strerror() a two liner.

My main concern is all the strings ending up shifted because of a
missing entry in the initializer array.

Understood. As you pointed out, I don't see much of a concern with this, since we'are be the only ones susceptible to break libusbx in such a fashion, and we're supposed to be paying attention to our own very prominent comments when adding an errcode.

tl;dr: Please add a sanity check on locale, ie, check that

(strlen(locale) == 2 ||
     (strlen(locale) > 2 &&
         (locale[2] == '_' || locale[2] == '.')))

is true, and otherwise return an invalid_param error, and then
lets go with your proposal.

As per the attached, here's what I'm planning to go with:

  if ( (locale == NULL) || (strlen(locale) < 2)
|| ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) )
    return LIBUSB_ERROR_INVALID_PARAM;

I added a dash in there, since Windows culture codes are of the form "nl-NL", "fr-BE", etc, and we should support these. Not sure if your underscore was actually intended, but even if it wasn't, I see no real harm having it.
I tested this check with xusb and it seemed to produce the expected results.

Note the strlen check in my proposed sanity check, some calling code
may very well end up passing in just "C", so the strlen check is
important!

Absolutely. Strings provided by a user can never be trusted in terms of length or their data being non-garbage.

Finally, as you'll see from the new proposal, I also added a doxygen comment to detail the steps translators should follow to add a translation.

Regards,

/Pete
>From e4d3ab2b9de7ece1071f03cd1661ff19d1d19e20 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdego...@redhat.com>
Date: Fri, 7 Jun 2013 19:07:16 +0100
Subject: [PATCH] Core: Add a libusb_strerror() function

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
---
 examples/xusb.c                         |  30 ++++--
 libusb/Makefile.am                      |   5 +-
 libusb/libusb-1.0.def                   |   8 +-
 libusb/libusb.h                         |  14 ++-
 libusb/libusbi.h                        |   4 +
 libusb/strerror.c                       | 182 ++++++++++++++++++++++++++++++++
 libusb/version_nano.h                   |   2 +-
 msvc/libusb_dll_2005.vcproj             |   4 +
 msvc/libusb_dll_2010.vcxproj            |   1 +
 msvc/libusb_dll_2010.vcxproj.filters    |   3 +
 msvc/libusb_dll_2012.vcxproj            |   1 +
 msvc/libusb_dll_2012.vcxproj.filters    |   3 +
 msvc/libusb_dll_wince.vcproj            |   4 +
 msvc/libusb_sources                     |   1 +
 msvc/libusb_static_2005.vcproj          |   4 +
 msvc/libusb_static_2010.vcxproj         |   1 +
 msvc/libusb_static_2010.vcxproj.filters |   3 +
 msvc/libusb_static_2012.vcxproj         |   1 +
 msvc/libusb_static_2012.vcxproj.filters |   3 +
 msvc/libusb_static_wince.vcproj         |   4 +
 20 files changed, 259 insertions(+), 19 deletions(-)
 create mode 100644 libusb/strerror.c

diff --git a/examples/xusb.c b/examples/xusb.c
index 4e2f6a5..cae3d82 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -64,7 +64,7 @@ static int perr(char const *format, ...)
        return r;
 }
 
-#define ERR_EXIT(errcode) do { perr("   %s\n", libusb_error_name((enum 
libusb_error)errcode)); return -1; } while (0)
+#define ERR_EXIT(errcode) do { perr("   %s\n", libusb_strerror((enum 
libusb_error)errcode)); return -1; } while (0)
 #define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
 #define B(x) (((x)!=0)?1:0)
 #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
@@ -354,7 +354,7 @@ static int send_mass_storage_command(libusb_device_handle 
*handle, uint8_t endpo
                i++;
        } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
        if (r != LIBUSB_SUCCESS) {
-               perr("   send_mass_storage_command: %s\n", 
libusb_error_name(r));
+               perr("   send_mass_storage_command: %s\n", 
libusb_strerror((enum libusb_error)r));
                return -1;
        }
 
@@ -378,7 +378,7 @@ static int get_mass_storage_status(libusb_device_handle 
*handle, uint8_t endpoin
                i++;
        } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
        if (r != LIBUSB_SUCCESS) {
-               perr("   get_mass_storage_status: %s\n", libusb_error_name(r));
+               perr("   get_mass_storage_status: %s\n", libusb_strerror((enum 
libusb_error)r));
                return -1;
        }
        if (size != 13) {
@@ -460,7 +460,7 @@ static int test_mass_storage(libusb_device_handle *handle, 
uint8_t endpoint_in,
        if (r == 0) {
                lun = 0;
        } else if (r < 0) {
-               perr("   Failed: %s", libusb_error_name((enum libusb_error)r));
+               perr("   Failed: %s", libusb_strerror((enum libusb_error)r));
        }
        printf("   Max LUN = %d\n", lun);
 
@@ -638,7 +638,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                                libusb_clear_halt(handle, 0);
                                break;
                        default:
-                               printf("   Error: %s\n", libusb_error_name(r));
+                               printf("   Error: %s\n", libusb_strerror((enum 
libusb_error)r));
                                break;
                        }
                }
@@ -669,7 +669,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                                libusb_clear_halt(handle, 0);
                                break;
                        default:
-                               printf("   Error: %s\n", libusb_error_name(r));
+                               printf("   Error: %s\n", libusb_strerror((enum 
libusb_error)r));
                                break;
                        }
                }
@@ -680,7 +680,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                if (r >= 0) {
                        display_buffer_hex(report_buffer, size);
                } else {
-                       printf("   %s\n", libusb_error_name(r));
+                       printf("   %s\n", libusb_strerror((enum 
libusb_error)r));
                }
 
                free(report_buffer);
@@ -715,7 +715,7 @@ static void 
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
                r = libusb_control_transfer(handle, 
(uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
                        bRequest, (uint16_t)(((iface_number)<< 8)|0x00), 
os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
                if (r < os_fd[i].header_size) {
-                       perr("   Failed: %s", (r<0)?libusb_error_name((enum 
libusb_error)r):"header size is too small");
+                       perr("   Failed: %s", (r<0)?libusb_strerror((enum 
libusb_error)r):"header size is too small");
                        return;
                }
                le_type_punning_IS_fine = (void*)os_desc;
@@ -728,7 +728,7 @@ static void 
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
                r = libusb_control_transfer(handle, 
(uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
                        bRequest, (uint16_t)(((iface_number)<< 8)|0x00), 
os_fd[i].index, os_desc, (uint16_t)length, 1000);
                if (r < 0) {
-                       perr("   Failed: %s", libusb_error_name((enum 
libusb_error)r));
+                       perr("   Failed: %s", libusb_strerror((enum 
libusb_error)r));
                        return;
                } else {
                        display_buffer_hex(os_desc, r);
@@ -977,6 +977,7 @@ int main(int argc, char** argv)
        size_t i, arglen;
        unsigned tmp_vid, tmp_pid;
        uint16_t endian_test = 0xBE00;
+       char* error_lang = NULL;
 
        // Default to generic, expecting VID:PID
        VID = 0;
@@ -1009,6 +1010,13 @@ int main(int argc, char** argv)
                                        binary_name = argv[++j];
                                        binary_dump = true;
                                        break;
+                               case 'l':
+                                       if ((j+1 >= argc) || (argv[j+1][0] == 
'-') || (argv[j+1][0] == '/')) {
+                                               printf("   Option -l requires 
an ISO 639-1 language parameter");
+                                               return 1;
+                                       }
+                                       error_lang = argv[++j];
+                                       break;
                                case 'j':
                                        // OLIMEX ARM-USB-TINY JTAG, 2 channel 
composite device - 2 interfaces
                                        if (!VID && !PID) {
@@ -1066,7 +1074,7 @@ int main(int argc, char** argv)
        }
 
        if ((show_help) || (argc == 1) || (argc > 7)) {
-               printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-j] [-x] [-s] 
[-p] [vid:pid]\n", argv[0]);
+               printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] 
[-x] [-s] [-p] [vid:pid]\n", argv[0]);
                printf("   -h      : display usage\n");
                printf("   -d      : enable debug output\n");
                printf("   -i      : print topology and speed info\n");
@@ -1076,6 +1084,7 @@ int main(int argc, char** argv)
                printf("   -p      : test Sony PS3 SixAxis controller\n");
                printf("   -s      : test Microsoft Sidewinder Precision Pro 
(HID)\n");
                printf("   -x      : test Microsoft XBox Controller Type S\n");
+               printf("   -l lang : language to report errors in (ISO 
639-1)\n");
                printf("If only the vid:pid is provided, xusb attempts to run 
the most appropriate test\n");
                return 0;
        }
@@ -1085,6 +1094,7 @@ int main(int argc, char** argv)
        r = libusb_init(NULL);
        if (r < 0)
                return r;
+       r = libusb_setlocale(error_lang);
 
        libusb_set_debug(NULL, 
debug_mode?LIBUSB_LOG_LEVEL_DEBUG:LIBUSB_LOG_LEVEL_INFO);
 
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..e6c46fd 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -78,6 +78,8 @@ EXPORTS
   libusb_get_pollfds@4 = libusb_get_pollfds
   libusb_get_port_number
   libusb_get_port_number@4 = libusb_get_port_number
+  libusb_get_port_numbers
+  libusb_get_port_numbers@12 = libusb_get_port_numbers
   libusb_get_port_path
   libusb_get_port_path@16 = libusb_get_port_path
   libusb_get_ss_endpoint_companion_descriptor
@@ -136,6 +138,10 @@ EXPORTS
   libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
   libusb_set_pollfd_notifiers
   libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
+  libusb_setlocale
+  libusb_setlocale@4 = libusb_setlocale
+  libusb_strerror
+  libusb_strerror@4 = libusb_strerror
   libusb_submit_transfer
   libusb_submit_transfer@4 = libusb_submit_transfer
   libusb_try_lock_events
@@ -148,5 +154,3 @@ EXPORTS
   libusb_unref_device@4 = libusb_unref_device
   libusb_wait_for_event
   libusb_wait_for_event@8 = libusb_wait_for_event
-  libusb_get_port_numbers
-  libusb_get_port_numbers@12 = libusb_get_port_numbers
diff --git a/libusb/libusb.h b/libusb/libusb.h
index d733c46..a56a687 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,13 +1088,16 @@ 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_COUNT below as well as the
+          message strings in strerror.c when adding new error codes here. */
 
        /** Other error */
        LIBUSB_ERROR_OTHER = -99,
 };
 
+/* Total number of error codes in enum libusb_error */
+#define LIBUSB_ERROR_COUNT 14
+
 /** \ingroup asyncio
  * Transfer status codes */
 enum libusb_transfer_status {
@@ -1299,6 +1303,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/libusbi.h b/libusb/libusbi.h
index eabf33d..d5e5c59 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -59,6 +59,10 @@
 /* The following is used to silence warnings for unused variables */
 #define UNUSED(var)                    do { (void)(var); } while(0)
 
+#if !defined(ARRAYSIZE)
+#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
+#endif
+
 struct list_head {
        struct list_head *prev, *next;
 };
diff --git a/libusb/strerror.c b/libusb/strerror.c
new file mode 100644
index 0000000..3d0fc2d
--- /dev/null
+++ b/libusb/strerror.c
@@ -0,0 +1,182 @@
+/*
+ * 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"
+
+#if defined(_MSC_VER)
+#define strncasecmp _strnicmp
+#endif
+
+static int usbi_locale = 0;
+
+/** \ingroup misc
+ * How to add a new libusb_strerror() translation:
+ * 1. Download the latest strerror.c from:
+ *    https://raw.github.com/libusbx/libusbx/master/libusb/sterror.c
+ * 2. Open the file in an UTF-8 capable editor
+ * 3. Add the 2 letter ISO 639-1 code for your locale at the end of 
usbi_locale_supported[]
+ *    using http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for the list 
of codes.
+ *    Eg. for Chinese, you would add "zh" so that:
+ *    \code... usbi_locale_supported[] = {"en", "nl", "fr" };\endcode
+ *    becomes:
+ *    \code... usbi_locale_supported[] = {"en", "nl", "fr", "zh" };\endcode
+ * 4. Copy the { /* English (en) * / ... } section and add it at the end of 
the usbi_localized_errors
+ *    Eg. for Chinese, the last section of usbi_localized_errors could look 
like:
+ *    \code}, { /* Chinese (zh) * /
+ *       "Success",
+ *       ...
+ *       "Other error",
+ *    }
+ *  }\endcode
+ * 5. Translate each of the english messages from the section you copied into 
your language.
+ * 6. Save the file (in UTF-8 format) and send it to 
libusbx-devel@lists.sourceforge.net
+ */
+
+static const char* usbi_locale_supported[] = {"en", "nl", "fr" };
+static const char* 
usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = {
+       { /* English (en) */
+               "Success",
+               "Input/Output Error",
+               "Invalid parameter",
+               "Access denied (insufficient permissions)",
+               "No such device (it may have been disconnected)",
+               "Entity not found",
+               "Resource busy",
+               "Operation timed out",
+               "Overflow",
+               "Pipe error",
+               "System call interrupted (perhaps due to signal)",
+               "Insufficient memory",
+               "Operation not supported or unimplemented on this platform",
+               "Other error",
+       }, { /* Dutch (nl) */
+               "Gelukt",
+               "Invoer-/uitvoerfout",
+               "Ongeldig argument",
+               "Toegang geweigerd (onvoldoende toegangsrechten)",
+               "Apparaat bestaat niet (verbinding met apparaat verbroken?)",
+               "Niet gevonden",
+               "Apparaat of hulpbron is bezig",
+               "Bewerking verlopen",
+               "Waarde is te groot",
+               "Gebroken pijp",
+               "Onderbroken systeemaanroep",
+               "Onvoldoende geheugen beschikbaar",
+               "Bewerking wordt niet ondersteund",
+               "Andere fout",
+       }, { /* French (fr) */
+               "Succès",
+               "Erreur d'entrée/sortie",
+               "Paramètre invalide",
+               "Accès refusé (permissions insuffisantes)",
+               "Périphérique introuvable (peut-être déconnecté)",
+               "Elément introuvable",
+               "Resource déjà occupée",
+               "Operation expirée",
+               "Débordement",
+               "Erreur de pipe",
+               "Appel système abandonné (peut-être à cause d’un signal)",
+               "Mémoire insuffisante",
+               "Opération non supportée or non implémentée sur cette 
plateforme",
+               "Autre erreur"
+       }
+};
+
+/** \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_region and codeset parts are ignored. This means that functions
+ * which return translatable strings will NOT honor the specified encoding.
+ * If locale 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 LIBUSB_SUCCESS 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)
+{
+       int i;
+
+       if ( (locale == NULL) || (strlen(locale) < 2)
+         || ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') 
&& (locale[2] != '.')) ) 
+               return LIBUSB_ERROR_INVALID_PARAM;
+
+       for (i=0; i<ARRAYSIZE(usbi_locale_supported); i++) {
+               if (strncasecmp(usbi_locale_supported[i], locale, 2) == 0)
+                       break;
+       }
+       if (i >= ARRAYSIZE(usbi_locale_supported)) {
+               usbi_warn(NULL, "Unrecognized locale format: %s", locale);
+               return LIBUSB_ERROR_NOT_FOUND;
+       }
+
+       usbi_locale = i;
+
+       return LIBUSB_SUCCESS;
+}
+
+/** \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_CALL libusb_strerror(enum libusb_error 
errcode)
+{
+       int errcode_index = -errcode;
+
+       if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) {
+               /* "Other Error", which should always be our last message, is 
returned */
+               errcode_index = LIBUSB_ERROR_COUNT - 1;
+       }
+
+       return usbi_localized_errors[usbi_locale][errcode_index];
+}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 2804c7d..47f4f0d 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10728
+#define LIBUSB_NANO 10733
diff --git a/msvc/libusb_dll_2005.vcproj b/msvc/libusb_dll_2005.vcproj
index 9a8f6c3..82e5af5 100644
--- a/msvc/libusb_dll_2005.vcproj
+++ b/msvc/libusb_dll_2005.vcproj
@@ -362,6 +362,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_dll_2010.vcxproj b/msvc/libusb_dll_2010.vcxproj
index 7648e57..7b435b2 100644
--- a/msvc/libusb_dll_2010.vcxproj
+++ b/msvc/libusb_dll_2010.vcxproj
@@ -143,6 +143,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_dll_2010.vcxproj.filters 
b/msvc/libusb_dll_2010.vcxproj.filters
index 40281f1..cc7d1aa 100644
--- a/msvc/libusb_dll_2010.vcxproj.filters
+++ b/msvc/libusb_dll_2010.vcxproj.filters
@@ -29,6 +29,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_dll_2012.vcxproj b/msvc/libusb_dll_2012.vcxproj
index 5920895..adcad4a 100644
--- a/msvc/libusb_dll_2012.vcxproj
+++ b/msvc/libusb_dll_2012.vcxproj
@@ -147,6 +147,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_dll_2012.vcxproj.filters 
b/msvc/libusb_dll_2012.vcxproj.filters
index fff52f0..ccada70 100644
--- a/msvc/libusb_dll_2012.vcxproj.filters
+++ b/msvc/libusb_dll_2012.vcxproj.filters
@@ -26,6 +26,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_dll_wince.vcproj b/msvc/libusb_dll_wince.vcproj
index 4238a4d..822404c 100644
--- a/msvc/libusb_dll_wince.vcproj
+++ b/msvc/libusb_dll_wince.vcproj
@@ -1161,6 +1161,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_sources b/msvc/libusb_sources
index ca9bed8..308a666 100644
--- a/msvc/libusb_sources
+++ b/msvc/libusb_sources
@@ -29,6 +29,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib
 SOURCES=..\core.c \
        ..\descriptor.c \
        ..\io.c \
+       ..\strerror.c \
        ..\sync.c \
        ..\hotplug.c \
        threads_windows.c \
diff --git a/msvc/libusb_static_2005.vcproj b/msvc/libusb_static_2005.vcproj
index 68c9e2c..f7b8e45 100644
--- a/msvc/libusb_static_2005.vcproj
+++ b/msvc/libusb_static_2005.vcproj
@@ -298,6 +298,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_static_2010.vcxproj b/msvc/libusb_static_2010.vcxproj
index 37ee80c..1958d11 100644
--- a/msvc/libusb_static_2010.vcxproj
+++ b/msvc/libusb_static_2010.vcxproj
@@ -133,6 +133,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_static_2010.vcxproj.filters 
b/msvc/libusb_static_2010.vcxproj.filters
index 74a29cd..5cd8060 100644
--- a/msvc/libusb_static_2010.vcxproj.filters
+++ b/msvc/libusb_static_2010.vcxproj.filters
@@ -23,6 +23,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_static_2012.vcxproj b/msvc/libusb_static_2012.vcxproj
index 7baa2ae..88605ba 100644
--- a/msvc/libusb_static_2012.vcxproj
+++ b/msvc/libusb_static_2012.vcxproj
@@ -137,6 +137,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_static_2012.vcxproj.filters 
b/msvc/libusb_static_2012.vcxproj.filters
index 74a29cd..5cd8060 100644
--- a/msvc/libusb_static_2012.vcxproj.filters
+++ b/msvc/libusb_static_2012.vcxproj.filters
@@ -23,6 +23,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_static_wince.vcproj b/msvc/libusb_static_wince.vcproj
index 54fd48d..a595319 100644
--- a/msvc/libusb_static_wince.vcproj
+++ b/msvc/libusb_static_wince.vcproj
@@ -1103,6 +1103,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
-- 
1.8.0.msysgit.0

------------------------------------------------------------------------------
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