8000 Merge remote-tracking branch 'micropython/master' · ladyada/circuitpython@a52fd67 · GitHub
[go: up one dir, main page]

Skip to content

Commit a52fd67

Browse files
committed
Merge remote-tracking branch 'micropython/master'
2 parents a6254f4 + 89bfbfd commit a52fd67

File tree

193 files changed

+15509
-49758
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

193 files changed

+15509
-49758
lines changed

cc3200/mods/modussl.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
7878
{ MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
7979
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
8080
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
81+
{ MP_QSTR_ssl_version, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SL_SO_SEC_METHOD_TLSV1} },
8182
{ MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
8283
};
8384

@@ -93,17 +94,19 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
9394
// retrieve the file paths (with an 6 byte offset in order to strip it from the '/flash' prefix)
9495
const char *keyfile = (args[1].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[1].u_obj)[6]);
9596
const char *certfile = (args[2].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[2].u_obj)[6]);
96-
const char *cafile = (args[5].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
97-
NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
97+
const char *cafile = (args[6].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
98+
NULL : &(mp_obj_str_get_str(args[6].u_obj)[6]);
9899

99100
// server side requires both certfile and keyfile
100101
if (args[3].u_bool && (!keyfile || !certfile)) {
101102
goto arg_error;
102103
}
103104

104-
_i16 sd = ((mod_network_socket_obj_t *)args[0].u_obj)->sock_base.sd;
105105
_i16 _errno;
106-
_u8 method = SL_SO_SEC_METHOD_TLSV1;
106+
_i16 sd = ((mod_network_socket_obj_t *)args[0].u_obj)->sock_base.sd;
107+
108+
// set the requested SSL method
109+
_u8 method = args[5].u_int;
107110
if ((_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method))) < 0) {
108111
goto socket_error;
109112
}
@@ -146,6 +149,11 @@ STATIC const mp_map_elem_t mp_module_ussl_globals_table[] = {
146149
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_NONE), MP_OBJ_NEW_SMALL_INT(SSL_CERT_NONE) },
147150
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_OPTIONAL), MP_OBJ_NEW_SMALL_INT(SSL_CERT_OPTIONAL) },
148151
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_REQUIRED), MP_OBJ_NEW_SMALL_INT(SSL_CERT_REQUIRED) },
152+
153+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_SSLv3), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_SSLV3) },
154+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1) },
155+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1_1), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1_1) },
156+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1_2), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1_2) },
149157
};
150158

151159
STATIC MP_DEFINE_CONST_DICT(mp_module_ussl_globals, mp_module_ussl_globals_table);

docs/library/machine.I2C.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ methods are convenience functions to communicate with such devices.
170170

171171
Read `nbytes` from the slave specified by `addr` starting from the memory
172172
address specified by `memaddr`.
173-
The argument `addrsize` specifies the address size in bits (on ESP8266
174-
this argument is not recognised and the address size is always 8 bits).
173+
The argument `addrsize` specifies the address size in bits.
175174
Returns a `bytes` object with the data read.
176175

177176
.. method:: I2C.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8)

docs/library/pyb.USB_HID.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ Constructors
2020
Methods
2121
-------
2222

23+
.. method:: USB_HID.recv(data, \*, timeout=5000)
24+
25+
Receive data on the bus:
26+
27+
- ``data`` can be an integer, which is the number of bytes to receive,
28+
or a mutable buffer, which will be filled with received bytes.
29+
- ``timeout`` is the timeout in milliseconds to wait for the receive.
30+
31+
Return value: if ``data`` is an integer then a new buffer of the bytes received,
32+
otherwise the number of bytes read into ``data`` is returned.
33+
2334
.. method:: USB_HID.send(data)
2435

2536
Send data over the USB HID interface:

docs/library/uos.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,29 @@ Functions
6161

6262
Get the status of a file or directory.
6363

64+
.. only:: port_unix or port_pyboard or port_esp8266
65+
66+
.. function:: statvfs(path)
67+
68+
Get the status of a fileystem.
69+
70+
Returns a tuple with the filesystem information in the following order:
71+
72+
* ``f_bsize`` -- file system block size
73+
* ``f_frsize`` -- fragment size
74+
* ``f_blocks`` -- size of fs in f_frsize units
75+
* ``f_bfree`` -- number of free blocks
76+
* ``f_bavail`` -- number of free blocks for unpriviliged users
77+
* ``f_files`` -- number of inodes
78+
* ``f_ffree`` -- number of free inodes
79+
* ``f_favail`` -- number of free inodes for unpriviliged users
80+
* ``f_flag`` -- mount flags
81+
* ``f_namemax`` -- maximum filename length
82+
83+
Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail``
84+
and the ``f_flags`` parameter may return ``0`` as they can be unavailable
85+
in a port-specific implementation.
86+
6487
.. function:: sync()
6588

6689
Sync all filesystems.

docs/wipy/general.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ all divisions must be performed using '//' instead of '/'. Example::
1414
Before applying power
1515
---------------------
1616

17-
.. warning::
17+
.. warning::
1818

1919
The GPIO pins of the WiPy are NOT 5V tolerant, connecting them to voltages higher
20-
than 3.6V will cause irreparable damage to the board. ADC pins, when configured
20+
than 3.6V will cause irreparable damage to the board. ADC pins, when configured
2121
in analog mode cannot withstand voltages above 1.8V. Keep these considerations in
2222
mind when wiring your electronics.
2323

2424
WLAN default behaviour
2525
----------------------
2626

27-
When the WiPy boots with the default factory configuration starts in Access Point
28-
mode with ``ssid`` that starts with: ``wipy-wlan`` and ``key: www.wipy.io``.
27+
When the WiPy boots with the default factory configuration starts in Access Point
28+
mode with ``ssid`` that starts with: ``wipy-wlan`` and ``key: www.wipy.io``.
2929
Connect to this network and the WiPy will be reachable at ``192.168.1.1``. In order
3030
to gain access to the interactive prompt, open a telnet session to that IP address on
3131
the default port (23). You will be asked for credentials:
@@ -98,7 +98,7 @@ the WiPy by pressing the switch on the board, or by typing::
9898
>>> import machine
9999
>>> machine.reset()
100100

101-
Software updates can be found in: https://github.com/wipy/wipy/releases (**Binaries.zip**).
101+
Software updates can be found in: https://github.com/wipy/wipy/releases (**Binaries.zip**).
102102
It's always recommended to update to the latest software, but make sure to
103103
read the **release notes** before.
104104

@@ -122,7 +122,7 @@ Boot modes and safe boot
122122
------------------------
123123

124124
If you power up normally, or press the reset button, the WiPy will boot
125-
into standard mode; the ``boot.py`` file will be executed first, then
125+
into standard mode; the ``boot.py`` file will be executed first, then
126126
``main.py`` will run.
127127

128128
You can override this boot sequence by pulling ``GP28`` **up** (connect
@@ -178,4 +178,4 @@ Details on sleep modes
178178
configuration required.
179179
* ``machine.sleep()``: 950uA (in WLAN STA mode). Wake sources are ``Pin``, ``RTC``
180180
and ``WLAN``
181-
* ``machine.deepsleep()``: ~5uA. Wake sources are ``Pin`` and ``RTC``.
181+
* ``machine.deepsleep()``: ~350uA. Wake sources are ``Pin`` and ``RTC``.

drivers/dht/dht.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,6 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
8484

8585
timeout:
8686
mp_hal_quiet_timing_exit(irq_state);
87-
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT)));
87+
mp_raise_OSError(MP_ETIMEDOUT);
8888
}
8989
MP_DEFINE_CONST_FUN_OBJ_2(dht_readinto_obj, dht_readinto);

esp8266/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ FROZEN_DIR = scripts
1818
FROZEN_MPY_DIR = modules
1919
PORT ?= /dev/ttyACM0
2020
BAUD ?= 115200
21+
FLASH_MODE ?= qio
22+
FLASH_SIZE ?= 8m
2123
CROSS_COMPILE = xtensa-lx106-elf-
2224
ESP_SDK = $(shell $(CC) -print-sysroot)/usr
2325

@@ -128,6 +130,7 @@ LIB_SRC_C = $(addprefix lib/,\
128130
timeutils/timeutils.c \
129131
utils/pyexec.c \
130132
utils/pyhelp.c \
133+
utils/interrupt_char.c \
131134
fatfs/ff.c \
132135
fatfs/option/ccsbcs.c \
133136
)
@@ -188,7 +191,7 @@ $(BUILD)/frozen_mpy.c: $(FROZEN_MPY_MPY_FILES) $(BUILD)/genhdr/qstrdefs.generate
188191

189192
deploy: $(BUILD)/firmware-combined.bin
190193
$(ECHO) "Writing $< to the board"
191-
$(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=8m 0 $<
194+
$(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $<
192195
#$(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --flash_size=8m 0 $(BUILD)/firmware.elf-0x00000.bin 0x9000 $(BUILD)/firmware.elf-0x0[1-f]000.bin
193196

194197
reset:

esp8266/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ $ make deploy
7070
```
7171
This will use the `esptool.py` script to download the images. You must have
7272
your ESP module in the bootloader mode, and connected to a serial port on your PC.
73-
The default serial port is `/dev/ttyACM0`. To specify another, use, eg:
73+
The default serial port is `/dev/ttyACM0`, flash mode is `qio` and flash size is `8m`.
74+
To specify other values, use, eg:
7475
```bash
75-
$ make PORT=/dev/ttyUSB0 deploy
76+
$ make PORT=/dev/ttyUSB0 FLASH_MODE=qio FLASH_SIZE=8m deploy
7677
```
7778

7879
The image produced is `firmware-combined.bin`, to be flashed at 0x00000.

esp8266/esp_mphal.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,6 @@ void mp_hal_delay_ms(uint32_t delay) {
128128
10000 mp_hal_delay_us(delay * 1000);
129129
}
130130

131-
void mp_hal_set_interrupt_char(int c) {
132-
if (c != -1) {
133-
mp_obj_exception_clear_traceback(MP_STATE_PORT(mp_kbd_exception));
134-
}
135-
extern int interrupt_char;
136-
interrupt_char = c;
137-
}
138-
139131
void ets_event_poll(void) {
140132
ets_loop_iter();
141133
if (MP_STATE_VM(mp_pending_exception) != NULL) {
@@ -180,7 +172,7 @@ static int call_dupterm_read(void) {
180172
mp_buffer_info_t bufinfo;
181173
mp_get_buffer_raise(MP_STATE_PORT(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
182174
nlr_pop();
183-
if (*(byte*)bufinfo.buf == interrupt_char) {
175+
if (*(byte*)bufinfo.buf == mp_interrupt_char) {
184176
mp_keyboard_interrupt();
185177
return -2;
186178
}

esp8266/esp_mphal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
#define _INCLUDED_MPHAL_H_
2929

3030
#include "py/ringbuf.h"
31+
#include "lib/utils/interrupt_char.h"
3132
#include "xtirq.h"
3233

3334
void mp_keyboard_interrupt(void);
34-
extern int interrupt_char;
3535

3636
struct _mp_print_t;
3737
// Structure for UART-only output via mp_printf()

esp8266/espneopixel.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus
66
// Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution.
77

8+
#include "py/mpconfig.h"
9+
#if MICROPY_ESP8266_NEOPIXEL
10+
811
#include "c_types.h"
912
#include "eagle_soc.h"
1013
#include "user_interface.h"
@@ -58,3 +61,5 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32
5861
while((mp_hal_ticks_cpu() - startTime) < period); // Wait for last bit
5962
mp_hal_quiet_timing_exit(irq_state);
6063
}
64+
65+
#endif // MICROPY_ESP8266_NEOPIXEL

esp8266/main.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ STATIC void mp_reset(void) {
4949
mp_init();
5050
mp_obj_list_init(mp_sys_path, 0);
5151
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
52-
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_));
5352
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
53+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_));
5454
mp_obj_list_init(mp_sys_argv, 0);
5555
#if MICROPY_VFS_FAT
5656
memset(MP_STATE_PORT(fs_user_mount), 0, sizeof(MP_STATE_PORT(fs_user_mount)));
@@ -141,10 +141,6 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
141141
}
142142
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
143143

144-
void mp_keyboard_interrupt(void) {
145-
MP_STATE_VM(mp_pending_exception) = MP_STATE_PORT(mp_kbd_exception);
146-
}
147-
148144
void nlr_jump_fail(void *val) {
149145
printf("NLR jump failed\n");
150146
for (;;) {

esp8266/modesp.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ STATIC mp_obj_t esp_flash_read(mp_obj_t offset_in, mp_obj_t len_or_buf_in) {
583583
if (alloc_buf) {
584584
m_del(byte, buf, len);
585585
}
586-
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO)));
586+
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
587587
}
588588
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_read_obj, esp_flash_read);
589589

@@ -598,9 +598,7 @@ STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, const mp_obj_t buf_in) {
598598
if (res == SPI_FLASH_RESULT_OK) {
599599
return mp_const_none;
600600
}
601-
nlr_raise(mp_obj_new_exception_arg1(
602-
&mp_type_OSError,
603-
MP_OBJ_NEW_SMALL_INT(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO)));
601+
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
604602
}
605603
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_write_obj, esp_flash_write);
606604

@@ -610,9 +608,7 @@ STATIC mp_obj_t esp_flash_erase(mp_obj_t sector_in) {
610608
if (res == SPI_FLASH_RESULT_OK) {
611609
return mp_const_none;
612610
}
613-
nlr_raise(mp_obj_new_exception_arg1(
614-
&mp_type_OSError,
615-
MP_OBJ_NEW_SMALL_INT(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO)));
611+
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
616612
}
617613
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_flash_erase_obj, esp_flash_erase);
618614

@@ -714,7 +710,9 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
714710
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&esp_socket_type },
715711
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&esp_getaddrinfo_obj },
716712
#endif
713+
#if MICROPY_ESP8266_NEOPIXEL
717714
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&esp_neopixel_write_obj },
715+
#endif
718716
#if MICROPY_ESP8266_APA102
719717
{ MP_OBJ_NEW_QSTR(MP_QSTR_apa102_write), (mp_obj_t)&esp_apa102_write_obj },
720718
#endif

esp8266/modmachine.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,10 @@ STATIC mp_obj_t machine_unique_id(void) {
8686
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
8787

8888
STATIC mp_obj_t machine_idle(void) {
89+
uint32_t t = mp_hal_ticks_cpu();
8990
asm("waiti 0");
90-
return mp_const_none;
91+
t = mp_hal_ticks_cpu() - t;
92+
return MP_OBJ_NEW_SMALL_INT(t);
9193
}
9294
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
9395

esp8266/modpybhspi.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,53 +50,41 @@ typedef struct _pyb_hspi_obj_t {
5050
} pyb_hspi_obj_t;
5151

5252

53-
STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
53+
STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
5454
(void)self_in;
5555

56-
if (dest_len == 0) {
56+
if (dest == NULL) {
5757
// fast case when we only need to write data
5858
size_t chunk_size = 1024;
59-
size_t count = src_len / chunk_size;
59+
size_t count = len / chunk_size;
6060
size_t i = 0;
6161
for (size_t j = 0; j < count; ++j) {
6262
for (size_t k = 0; k < chunk_size; ++k) {
63-
spi_tx8fast(HSPI, src_buf[i]);
63+
spi_tx8fast(HSPI, src[i]);
6464
++i;
6565
}
6666
ets_loop_iter();
6767
}
68-
while (i < src_len) {
69-
spi_tx8fast(HSPI, src_buf[i]);
68+
while (i < len) {
69+
spi_tx8fast(HSPI, src[i]);
7070
++i;
7171
}
7272
} else {
7373
// we need to read and write data
7474

7575
// Process data in chunks, let the pending tasks run in between
7676
size_t chunk_size = 1024; // TODO this should depend on baudrate
77-
size_t count = dest_len / chunk_size;
77+
size_t count = len / chunk_size;
7878
size_t i = 0;
7979
for (size_t j = 0; j < count; ++j) {
8080
for (size_t k = 0; k < chunk_size; ++k) {
81-
uint32_t data_out;
82-
if (src_len == 1) {
83-
data_out = src_buf[0];
84-
} else {
85-
data_out = src_buf[i];
86-
}
87-
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
81+
dest[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, src[i], 8, 0);
8882
++i;
8983
}
9084
ets_loop_iter();
9185
}
92-
while (i < dest_len) {
93-
uint32_t data_out;
94-
if (src_len == 1) {
95-
data_out = src_buf[0];
96-
} else {
97-
data_out = src_buf[i];
98-
}
99-
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
86+
while (i < len) {
87+
dest[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, src[i], 8, 0);
10088
++i;
10189
}
10290
}

0 commit comments

Comments
 (0)
0