libusb 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
@@ -0,0 +1,107 @@
1
+ /*
2
+ * libusbx test library helper functions
3
+ * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #ifndef LIBUSBX_TESTLIB_H
21
+ #define LIBUSBX_TESTLIB_H
22
+
23
+ #include <stdio.h>
24
+
25
+ #if !defined(bool)
26
+ #define bool int
27
+ #endif
28
+ #if !defined(true)
29
+ #define true (1 == 1)
30
+ #endif
31
+ #if !defined(false)
32
+ #define false (!true)
33
+ #endif
34
+
35
+ /** Values returned from a test function to indicate test result */
36
+ typedef enum {
37
+ /** Indicates that the test ran successfully. */
38
+ TEST_STATUS_SUCCESS,
39
+ /** Indicates that the test failed one or more test. */
40
+ TEST_STATUS_FAILURE,
41
+ /** Indicates that an unexpected error occurred. */
42
+ TEST_STATUS_ERROR,
43
+ /** Indicates that the test can't be run. For example this may be
44
+ * due to no suitable device being connected to perform the tests.*/
45
+ TEST_STATUS_SKIP
46
+ } libusbx_testlib_result;
47
+
48
+ /**
49
+ * Context for test library functions
50
+ */
51
+ typedef struct {
52
+ char ** test_names;
53
+ int test_count;
54
+ bool list_tests;
55
+ bool verbose;
56
+ int old_stdout;
57
+ int old_stderr;
58
+ FILE* output_file;
59
+ int null_fd;
60
+ } libusbx_testlib_ctx;
61
+
62
+ /**
63
+ * Logs some test information or state
64
+ */
65
+ void libusbx_testlib_logf(libusbx_testlib_ctx * ctx,
66
+ const char* fmt, ...);
67
+
68
+ /**
69
+ * Function pointer for a libusbx test function.
70
+ *
71
+ * Should return TEST_STATUS_SUCCESS on success or another TEST_STATUS value.
72
+ */
73
+ typedef libusbx_testlib_result
74
+ (*libusbx_testlib_test_function)(libusbx_testlib_ctx * ctx);
75
+
76
+ /**
77
+ * Structure holding a test description.
78
+ */
79
+ typedef struct {
80
+ /** Human readable name of the test. */
81
+ const char * name;
82
+ /** The test library will call this function to run the test. */
83
+ libusbx_testlib_test_function function;
84
+ } libusbx_testlib_test;
85
+
86
+ /**
87
+ * Value to use at the end of a test array to indicate the last
88
+ * element.
89
+ */
90
+ #define LIBUSBX_NULL_TEST {NULL, NULL}
91
+
92
+ /**
93
+ * Runs the tests provided.
94
+ *
95
+ * Before running any tests argc and argv will be processed
96
+ * to determine the mode of operation.
97
+ *
98
+ * \param argc The argc from main
99
+ * \param argv The argv from main
100
+ * \param tests A NULL_TEST terminated array of tests
101
+ * \return 0 on success, non-zero on failure
102
+ */
103
+ int libusbx_testlib_run_tests(int argc,
104
+ char ** argv,
105
+ const libusbx_testlib_test * tests);
106
+
107
+ #endif //LIBUSBX_TESTLIB_H
@@ -0,0 +1,160 @@
1
+ /*
2
+ * libusbx stress test program to perform simple stress tests
3
+ * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #include <stdio.h>
21
+ #include <string.h>
22
+ #include <memory.h>
23
+
24
+ #include "libusb.h"
25
+ #include "libusbx_testlib.h"
26
+
27
+ /** Test that creates and destroys a single concurrent context
28
+ * 10000 times. */
29
+ static libusbx_testlib_result test_init_and_exit(libusbx_testlib_ctx * tctx)
30
+ {
31
+ libusb_context * ctx = NULL;
32
+ int i;
33
+ for (i = 0; i < 10000; ++i) {
34
+ int r = libusb_init(&ctx);
35
+ if (r != LIBUSB_SUCCESS) {
36
+ libusbx_testlib_logf(tctx,
37
+ "Failed to init libusb on iteration %d: %d",
38
+ i, r);
39
+ return TEST_STATUS_FAILURE;
40
+ }
41
+ libusb_exit(ctx);
42
+ ctx = NULL;
43
+ }
44
+
45
+ return TEST_STATUS_SUCCESS;
46
+ }
47
+
48
+ /** Tests that devices can be listed 1000 times. */
49
+ static libusbx_testlib_result test_get_device_list(libusbx_testlib_ctx * tctx)
50
+ {
51
+ libusb_context * ctx = NULL;
52
+ int r, i;
53
+ r = libusb_init(&ctx);
54
+ if (r != LIBUSB_SUCCESS) {
55
+ libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
56
+ return TEST_STATUS_FAILURE;
57
+ }
58
+ for (i = 0; i < 1000; ++i) {
59
+ libusb_device ** device_list;
60
+ ssize_t list_size = libusb_get_device_list(ctx, &device_list);
61
+ if (list_size < 0 || device_list == NULL) {
62
+ libusbx_testlib_logf(tctx,
63
+ "Failed to get device list on iteration %d: %d (%p)",
64
+ i, -list_size, device_list);
65
+ return TEST_STATUS_FAILURE;
66
+ }
67
+ libusb_free_device_list(device_list, 1);
68
+ }
69
+ libusb_exit(ctx);
70
+ return TEST_STATUS_SUCCESS;
71
+ }
72
+
73
+ /** Tests that 100 concurrent device lists can be open at a time. */
74
+ static libusbx_testlib_result test_many_device_lists(libusbx_testlib_ctx * tctx)
75
+ {
76
+ #define LIST_COUNT 100
77
+ libusb_context * ctx = NULL;
78
+ libusb_device ** device_lists[LIST_COUNT];
79
+ int r, i;
80
+ memset(device_lists, 0, sizeof(device_lists));
81
+
82
+ r = libusb_init(&ctx);
83
+ if (r != LIBUSB_SUCCESS) {
84
+ libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
85
+ return TEST_STATUS_FAILURE;
86
+ }
87
+
88
+ /* Create the 100 device lists. */
89
+ for (i = 0; i < LIST_COUNT; ++i) {
90
+ ssize_t list_size = libusb_get_device_list(ctx, &(device_lists[i]));
91
+ if (list_size < 0 || device_lists[i] == NULL) {
92
+ libusbx_testlib_logf(tctx,
93
+ "Failed to get device list on iteration %d: %d (%p)",
94
+ i, -list_size, device_lists[i]);
95
+ return TEST_STATUS_FAILURE;
96
+ }
97
+ }
98
+
99
+ /* Destroy the 100 device lists. */
100
+ for (i = 0; i < LIST_COUNT; ++i) {
101
+ if (device_lists[i]) {
102
+ libusb_free_device_list(device_lists[i], 1);
103
+ device_lists[i] = NULL;
104
+ }
105
+ }
106
+
107
+ libusb_exit(ctx);
108
+ return TEST_STATUS_SUCCESS;
109
+ #undef LIST_COUNT
110
+ }
111
+
112
+ /** Tests that the default context (used for various things including
113
+ * logging) works correctly when the first context created in a
114
+ * process is destroyed. */
115
+ static libusbx_testlib_result test_default_context_change(libusbx_testlib_ctx * tctx)
116
+ {
117
+ libusb_context * ctx = NULL;
118
+ int r, i;
119
+
120
+ for (i = 0; i < 100; ++i) {
121
+ /* First create a new context */
122
+ r = libusb_init(&ctx);
123
+ if (r != LIBUSB_SUCCESS) {
124
+ libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
125
+ return TEST_STATUS_FAILURE;
126
+ }
127
+
128
+ /* Enable debug output, to be sure to use the context */
129
+ libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG);
130
+ libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_DEBUG);
131
+
132
+ /* Now create a reference to the default context */
133
+ r = libusb_init(NULL);
134
+ if (r != LIBUSB_SUCCESS) {
135
+ libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
136
+ return TEST_STATUS_FAILURE;
137
+ }
138
+
139
+ /* Destroy the first context */
140
+ libusb_exit(ctx);
141
+ /* Destroy the default context */
142
+ libusb_exit(NULL);
143
+ }
144
+
145
+ return TEST_STATUS_SUCCESS;
146
+ }
147
+
148
+ /* Fill in the list of tests. */
149
+ static const libusbx_testlib_test tests[] = {
150
+ {"init_and_exit", &test_init_and_exit},
151
+ {"get_device_list", &test_get_device_list},
152
+ {"many_device_lists", &test_many_device_lists},
153
+ {"default_context_change", &test_default_context_change},
154
+ LIBUSBX_NULL_TEST
155
+ };
156
+
157
+ int main (int argc, char ** argv)
158
+ {
159
+ return libusbx_testlib_run_tests(argc, argv, tests);
160
+ }
@@ -0,0 +1,276 @@
1
+ /*
2
+ * libusbx test library helper functions
3
+ * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #include "libusbx_testlib.h"
21
+
22
+ #include <stdio.h>
23
+ #include <stdarg.h>
24
+ #include <string.h>
25
+ #include <errno.h>
26
+ #if !defined(_WIN32_WCE)
27
+ #include <sys/types.h>
28
+ #include <sys/stat.h>
29
+ #include <fcntl.h>
30
+ #endif
31
+
32
+ #if defined(_WIN32_WCE)
33
+ // No support for selective redirection of STDOUT on WinCE.
34
+ #define DISABLE_STDOUT_REDIRECTION
35
+ #define STDOUT_FILENO 1
36
+ #elif defined(_WIN32)
37
+ #include <io.h>
38
+ #define dup _dup
39
+ #define dup2 _dup2
40
+ #define open _open
41
+ #define close _close
42
+ #define fdopen _fdopen
43
+ #define NULL_PATH "nul"
44
+ #define STDOUT_FILENO 1
45
+ #define STDERR_FILENO 2
46
+ #else
47
+ #include <unistd.h>
48
+ #define NULL_PATH "/dev/null"
49
+ #endif
50
+ #define INVALID_FD -1
51
+ #define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
52
+
53
+ /**
54
+ * Converts a test result code into a human readable string.
55
+ */
56
+ static const char* test_result_to_str(libusbx_testlib_result result)
57
+ {
58
+ switch (result) {
59
+ case TEST_STATUS_SUCCESS:
60
+ return "Success";
61
+ case TEST_STATUS_FAILURE:
62
+ return "Failure";
63
+ case TEST_STATUS_ERROR:
64
+ return "Error";
65
+ case TEST_STATUS_SKIP:
66
+ return "Skip";
67
+ default:
68
+ return "Unknown";
69
+ }
70
+ }
71
+
72
+ static void print_usage(int argc, char ** argv)
73
+ {
74
+ printf("Usage: %s [-l] [-v] [<test_name> ...]\n",
75
+ argc > 0 ? argv[0] : "test_*");
76
+ printf(" -l List available tests\n");
77
+ printf(" -v Don't redirect STDERR/STDOUT during tests\n");
78
+ }
79
+
80
+ static void cleanup_test_output(libusbx_testlib_ctx * ctx)
81
+ {
82
+ #ifndef DISABLE_STDOUT_REDIRECTION
83
+ if (!ctx->verbose) {
84
+ if (ctx->old_stdout != INVALID_FD) {
85
+ IGNORE_RETVAL(dup2(ctx->old_stdout, STDOUT_FILENO));
86
+ ctx->old_stdout = INVALID_FD;
87
+ }
88
+ if (ctx->old_stderr != INVALID_FD) {
89
+ IGNORE_RETVAL(dup2(ctx->old_stderr, STDERR_FILENO));
90
+ ctx->old_stderr = INVALID_FD;
91
+ }
92
+ if (ctx->null_fd != INVALID_FD) {
93
+ close(ctx->null_fd);
94
+ ctx->null_fd = INVALID_FD;
95
+ }
96
+ if (ctx->output_file != stdout) {
97
+ fclose(ctx->output_file);
98
+ ctx->output_file = stdout;
99
+ }
100
+ }
101
+ #endif
102
+ }
103
+
104
+ /**
105
+ * Setup test output handles
106
+ * \return zero on success, non-zero on failure
107
+ */
108
+ static int setup_test_output(libusbx_testlib_ctx * ctx)
109
+ {
110
+ #ifndef DISABLE_STDOUT_REDIRECTION
111
+ /* Stop output to stdout and stderr from being displayed if using non-verbose output */
112
+ if (!ctx->verbose) {
113
+ /* Keep a copy of STDOUT and STDERR */
114
+ ctx->old_stdout = dup(STDOUT_FILENO);
115
+ if (ctx->old_stdout < 0) {
116
+ ctx->old_stdout = INVALID_FD;
117
+ printf("Failed to duplicate stdout handle: %d\n", errno);
118
+ return 1;
119
+ }
120
+ ctx->old_stderr = dup(STDERR_FILENO);
121
+ if (ctx->old_stderr < 0) {
122
+ ctx->old_stderr = INVALID_FD;
123
+ cleanup_test_output(ctx);
124
+ printf("Failed to duplicate stderr handle: %d\n", errno);
125
+ return 1;
126
+ }
127
+ /* Redirect STDOUT_FILENO and STDERR_FILENO to /dev/null or "nul"*/
128
+ ctx->null_fd = open(NULL_PATH, O_WRONLY);
129
+ if (ctx->null_fd < 0) {
130
+ ctx->null_fd = INVALID_FD;
131
+ cleanup_test_output(ctx);
132
+ printf("Failed to open null handle: %d\n", errno);
133
+ return 1;
134
+ }
135
+ if ((dup2(ctx->null_fd, STDOUT_FILENO) < 0) ||
136
+ (dup2(ctx->null_fd, STDERR_FILENO) < 0)) {
137
+ cleanup_test_output(ctx);
138
+ return 1;
139
+ }
140
+ ctx->output_file = fdopen(ctx->old_stdout, "w");
141
+ if (!ctx->output_file) {
142
+ cleanup_test_output(ctx);
143
+ printf("Failed to open FILE for output handle: %d\n", errno);
144
+ return 1;
145
+ }
146
+ }
147
+ #endif
148
+ return 0;
149
+ }
150
+
151
+ void libusbx_testlib_logf(libusbx_testlib_ctx * ctx,
152
+ const char* fmt, ...)
153
+ {
154
+ va_list va;
155
+ va_start(va, fmt);
156
+ vfprintf(ctx->output_file, fmt, va);
157
+ va_end(va);
158
+ fprintf(ctx->output_file, "\n");
159
+ fflush(ctx->output_file);
160
+ }
161
+
162
+ int libusbx_testlib_run_tests(int argc,
163
+ char ** argv,
164
+ const libusbx_testlib_test * tests)
165
+ {
166
+ int run_count = 0;
167
+ int idx = 0;
168
+ int pass_count = 0;
169
+ int fail_count = 0;
170
+ int error_count = 0;
171
+ int skip_count = 0;
172
+ int r, j;
173
+ size_t arglen;
174
+ libusbx_testlib_result test_result;
175
+ libusbx_testlib_ctx ctx;
176
+
177
+ /* Setup default mode of operation */
178
+ ctx.test_names = NULL;
179
+ ctx.test_count = 0;
180
+ ctx.list_tests = false;
181
+ ctx.verbose = false;
182
+ ctx.old_stdout = INVALID_FD;
183
+ ctx.old_stderr = INVALID_FD;
184
+ ctx.output_file = stdout;
185
+ ctx.null_fd = INVALID_FD;
186
+
187
+ /* Parse command line options */
188
+ if (argc >= 2) {
189
+ for (j = 1; j < argc; j++) {
190
+ arglen = strlen(argv[j]);
191
+ if ( ((argv[j][0] == '-') || (argv[j][0] == '/')) &&
192
+ arglen >=2 ) {
193
+ switch (argv[j][1]) {
194
+ case 'l':
195
+ ctx.list_tests = true;
196
+ break;
197
+ case 'v':
198
+ ctx.verbose = true;
199
+ break;
200
+ default:
201
+ printf("Unknown option: '%s'\n", argv[j]);
202
+ print_usage(argc, argv);
203
+ return 1;
204
+ }
205
+ } else {
206
+ /* End of command line options, remaining must be list of tests to run */
207
+ ctx.test_names = argv + j;
208
+ ctx.test_count = argc - j;
209
+ break;
210
+ }
211
+ }
212
+ }
213
+
214
+ /* Validate command line options */
215
+ if (ctx.test_names && ctx.list_tests) {
216
+ printf("List of tests requested but test list provided\n");
217
+ print_usage(argc, argv);
218
+ return 1;
219
+ }
220
+
221
+ /* Setup test log output */
222
+ r = setup_test_output(&ctx);
223
+ if (r != 0)
224
+ return r;
225
+
226
+ /* Act on any options not related to running tests */
227
+ if (ctx.list_tests) {
228
+ while (tests[idx].function != NULL) {
229
+ libusbx_testlib_logf(&ctx, tests[idx].name);
230
+ ++idx;
231
+ }
232
+ cleanup_test_output(&ctx);
233
+ return 0;
234
+ }
235
+
236
+ /* Run any requested tests */
237
+ while (tests[idx].function != NULL) {
238
+ const libusbx_testlib_test * test = &tests[idx];
239
+ ++idx;
240
+ if (ctx.test_count > 0) {
241
+ /* Filtering tests to run, check if this is one of them */
242
+ int i;
243
+ for (i = 0; i < ctx.test_count; ++i) {
244
+ if (strcmp(ctx.test_names[i], test->name) == 0)
245
+ /* Matches a requested test name */
246
+ break;
247
+ }
248
+ if (i >= ctx.test_count) {
249
+ /* Failed to find a test match, so do the next loop iteration */
250
+ continue;
251
+ }
252
+ }
253
+ libusbx_testlib_logf(&ctx,
254
+ "Starting test run: %s...", test->name);
255
+ test_result = test->function(&ctx);
256
+ libusbx_testlib_logf(&ctx,
257
+ "%s (%d)",
258
+ test_result_to_str(test_result), test_result);
259
+ switch (test_result) {
260
+ case TEST_STATUS_SUCCESS: pass_count++; break;
261
+ case TEST_STATUS_FAILURE: fail_count++; break;
262
+ case TEST_STATUS_ERROR: error_count++; break;
263
+ case TEST_STATUS_SKIP: skip_count++; break;
264
+ }
265
+ ++run_count;
266
+ }
267
+ libusbx_testlib_logf(&ctx, "---");
268
+ libusbx_testlib_logf(&ctx, "Ran %d tests", run_count);
269
+ libusbx_testlib_logf(&ctx, "Passed %d tests", pass_count);
270
+ libusbx_testlib_logf(&ctx, "Failed %d tests", fail_count);
271
+ libusbx_testlib_logf(&ctx, "Error in %d tests", error_count);
272
+ libusbx_testlib_logf(&ctx, "Skipped %d tests", skip_count);
273
+
274
+ cleanup_test_output(&ctx);
275
+ return pass_count != run_count;
276
+ }