Merge pull request #8508 from dhalbert/v1.21-merge

V1.21 merge
This commit is contained in:
Scott Shawcroft 2023-10-24 15:36:06 -07:00 committed by GitHub
commit 168c40e940
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
540 changed files with 8472 additions and 3807 deletions

View File

@ -1,3 +1,9 @@
# all: Fix various spelling mistakes found by codespell 2.2.6.
cf490a70917a1b2d38ba9b58e763e0837d0f7ca7
# all: Fix spelling mistakes based on codespell check.
b1229efbd1509654dec6053865ab828d769e29db
# top: Update Python formatting to black "2023 stable style". # top: Update Python formatting to black "2023 stable style".
8b2748269244304854b3462cb8902952b4dcb892 8b2748269244304854b3462cb8902952b4dcb892

View File

@ -57,11 +57,10 @@ jobs:
run: | run: |
make -C examples/natmod/features1 make -C examples/natmod/features1
make -C examples/natmod/features2 make -C examples/natmod/features2
make -C examples/natmod/uheapq make -C examples/natmod/heapq
make -C examples/natmod/urandom make -C examples/natmod/random
make -C examples/natmod/ure make -C examples/natmod/re
make -C examples/natmod/uzlib
- name: Test native modules - name: Test native modules
if: matrix.test == 'all' if: matrix.test == 'all'
run: ./run-natmodtests.py extmod/{uheapq*,ure*,uzlib*}.py run: ./run-natmodtests.py extmod/{heapq*,re*,zlib*}.py
working-directory: tests working-directory: tests

View File

@ -24,7 +24,7 @@ Functions
.. function:: mem_alloc() .. function:: mem_alloc()
Return the number of bytes of heap RAM that are allocated. Return the number of bytes of heap RAM that are allocated by Python code.
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention
@ -33,8 +33,8 @@ Functions
.. function:: mem_free() .. function:: mem_free()
Return the number of bytes of available heap RAM, or -1 if this amount Return the number of bytes of heap RAM that is available for Python
is not known. code to allocate, or -1 if this amount is not known.
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention

View File

@ -17,7 +17,7 @@ limited flash memory:
``binascii``, ``errno``, ``json``, ``re``. ``binascii``, ``errno``, ``json``, ``re``.
These libraries are not currently enabled in any CircuitPython build, but may be in the future: These libraries are not currently enabled in any CircuitPython build, but may be in the future:
``ctypes`` ``ctypes``, ``platform``
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
@ -31,6 +31,7 @@ These libraries are not currently enabled in any CircuitPython build, but may be
gc.rst gc.rst
io.rst io.rst
json.rst json.rst
platform.rst
re.rst re.rst
sys.rst sys.rst
ctypes.rst ctypes.rst

38
docs/library/platform.rst Normal file
View File

@ -0,0 +1,38 @@
:mod:`platform` -- access to underlying platforms identifying data
===================================================================
.. module:: platform
:synopsis: access to underlying platforms identifying data
|see_cpython_module| :mod:`python:platform`.
This module tries to retrieve as much platform-identifying data as possible. It
makes this information available via function APIs.
Functions
---------
.. function:: platform()
Returns a string identifying the underlying platform. This string is composed
of several substrings in the following order, delimited by dashes (``-``):
- the name of the platform system (e.g. Unix, Windows or MicroPython)
- the MicroPython version
- the architecture of the platform
- the version of the underlying platform
- the concatenation of the name of the libc that MicroPython is linked to
and its corresponding version.
For example, this could be
``"MicroPython-1.20.0-xtensa-IDFv4.2.4-with-newlib3.0.0"``.
.. function:: python_compiler()
Returns a string identifying the compiler used for compiling MicroPython.
.. function:: libc_ver()
Returns a tuple of strings *(lib, version)*, where *lib* is the name of the
libc that MicroPython is linked to, and *version* the corresponding version
of this libc.

View File

@ -33,6 +33,7 @@ Constants
* *name* - string "circuitpython" * *name* - string "circuitpython"
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0) * *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
* *_machine* - string describing the underlying machine
* *_mpy* - supported mpy file-format version (optional attribute) * *_mpy* - supported mpy file-format version (optional attribute)
This object is the recommended way to distinguish CircuitPython from other This object is the recommended way to distinguish CircuitPython from other

View File

@ -32,7 +32,7 @@ Glossary
callee-owned tuple callee-owned tuple
This is a MicroPython-specific construct where, for efficiency This is a MicroPython-specific construct where, for efficiency
reasons, some built-in functions or methods may re-use the same reasons, some built-in functions or methods may reuse the same
underlying tuple object to return data. This avoids having to allocate underlying tuple object to return data. This avoids having to allocate
a new tuple for every call, and reduces heap fragmentation. Programs a new tuple for every call, and reduces heap fragmentation. Programs
should not hold references to callee-owned tuples and instead only should not hold references to callee-owned tuples and instead only
@ -120,7 +120,7 @@ Glossary
<https://github.com/micropython/micropython-lib>`_ which provides <https://github.com/micropython/micropython-lib>`_ which provides
implementations for many modules from CPython's standard library. implementations for many modules from CPython's standard library.
Some of the modules are are implemented in pure Python, and are able to Some of the modules are implemented in pure Python, and are able to
be used on all ports. However, the majority of these modules use be used on all ports. However, the majority of these modules use
:term:`FFI` to access operating system functionality, and as such can :term:`FFI` to access operating system functionality, and as such can
only be used on the :term:`MicroPython Unix port` (with limited support only be used on the :term:`MicroPython Unix port` (with limited support

View File

@ -63,7 +63,7 @@ ALIASES_BRAND_NAMES = {
} }
ADDITIONAL_MODULES = { ADDITIONAL_MODULES = {
"_asyncio": "MICROPY_PY_UASYNCIO", "_asyncio": "MICROPY_PY_ASYNCIO",
"adafruit_bus_device": "CIRCUITPY_BUSDEVICE", "adafruit_bus_device": "CIRCUITPY_BUSDEVICE",
"adafruit_pixelbuf": "CIRCUITPY_PIXELBUF", "adafruit_pixelbuf": "CIRCUITPY_PIXELBUF",
"array": "CIRCUITPY_ARRAY", "array": "CIRCUITPY_ARRAY",
@ -79,7 +79,7 @@ ADDITIONAL_MODULES = {
"keypad.Keys": "CIRCUITPY_KEYPAD_KEYS", "keypad.Keys": "CIRCUITPY_KEYPAD_KEYS",
"keypad.ShiftRegisterKeys": "CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS", "keypad.ShiftRegisterKeys": "CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS",
"os.getenv": "CIRCUITPY_OS_GETENV", "os.getenv": "CIRCUITPY_OS_GETENV",
"select": "MICROPY_PY_USELECT_SELECT", "select": "MICROPY_PY_SELECT_SELECT",
"sys": "CIRCUITPY_SYS", "sys": "CIRCUITPY_SYS",
"terminalio": "CIRCUITPY_DISPLAYIO", "terminalio": "CIRCUITPY_DISPLAYIO",
"usb": "CIRCUITPY_USB_HOST", "usb": "CIRCUITPY_USB_HOST",

74
examples/natmod/README.md Normal file
View File

@ -0,0 +1,74 @@
# Dynamic Native Modules
Dynamic Native Modules are .mpy files that contain native machine code from a
language other than Python. For more info see [the documentation]
(https://docs.micropython.org/en/latest/develop/natmod.html).
This should not be confused with [User C Modules]
(https://docs.micropython.org/en/latest/develop/cmodules.html) which are a
mechanism to add additional out-of-tree modules into the firmware build.
## Examples
This directory contains several examples of writing dynamic native modules, in
two main categories:
1. Feature examples.
* `features0` - A module containing a single "factorial" function which
demonstrates working with integers.
* `features1` - A module that demonstrates some common tasks:
- defining simple functions exposed to Python
- defining local, helper C functions
- defining constant integers and strings exposed to Python
- getting and creating integer objects
- creating Python lists
- raising exceptions
- allocating memory
- BSS and constant data (rodata)
- relocated pointers in rodata
* `features2` - This is a hybrid module containing both Python and C code,
and additionally the C code is spread over multiple files. It also
demonstrates using floating point (only when the target supports
hardware floating point).
* `features3` - A module that shows how to use types, constant objects,
and creating dictionary instances.
* `features4` - A module that demonstrates how to define a class.
2. Dynamic version of existing built-ins.
This provides a way to add missing functionality to firmware that doesn't
include certain built-in modules. See the `heapq`, `random`, `re`,
`deflate`, `btree`, and `framebuf` directories.
So for example, if your firmware was compiled with `MICROPY_PY_FRAMEBUF`
disabled (e.g. to save flash space), then it would not include the
`framebuf` module. The `framebuf` native module provides a way to add the
`framebuf` module dynamically.
The way these work is they define a dynamic native module which
`#include`'s the original module and then does the necessary
initialisation of the module's globals dict.
## Build instructions
To compile an example, you need to have the same toolchain available as
required for your target port. e.g. `arm-none-eabi-gcc` for any ARM Cortex M
target. See the port instructions for details.
You also need to have the `pyelftools` Python package available, either via
your system package manager or installed from PyPI in a virtual environment
with `pip`.
Each example provides a Makefile. You should specify the `ARCH` argument to
make (one of x86, x64, armv6m, armv7m, xtensa, xtensawin):
```
$ cd features0
$ make ARCH=armv7m
$ mpremote cp features0.mpy :
```

View File

@ -2,10 +2,10 @@
MPY_DIR = ../../.. MPY_DIR = ../../..
# Name of module (different to built-in uzlib so it can coexist) # Name of module (different to built-in uzlib so it can coexist)
MOD = uzlib_$(ARCH) MOD = deflate_$(ARCH)
# Source files (.c or .py) # Source files (.c or .py)
SRC = uzlib.c SRC = deflate.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64 ARCH = x64

View File

@ -0,0 +1,70 @@
#define MICROPY_PY_DEFLATE (1)
#define MICROPY_PY_DEFLATE_COMPRESS (1)
#include "py/dynruntime.h"
#if !defined(__linux__)
void *memcpy(void *dst, const void *src, size_t n) {
return mp_fun_table.memmove_(dst, src, n);
}
void *memset(void *s, int c, size_t n) {
return mp_fun_table.memset_(s, c, n);
}
#endif
mp_obj_full_type_t deflateio_type;
#include "extmod/moddeflate.c"
// Re-implemented from py/stream.c, not yet available in dynruntime.h.
mp_obj_t mp_stream_close(mp_obj_t stream) {
const mp_stream_p_t *stream_p = mp_get_stream(stream);
int error;
mp_uint_t res = stream_p->ioctl(stream, MP_STREAM_CLOSE, 0, &error);
if (res == MP_STREAM_ERROR) {
mp_raise_OSError(error);
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_close_obj, mp_stream_close);
// Re-implemented from py/stream.c, not yet available in dynruntime.h.
STATIC mp_obj_t mp_stream___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;
return mp_stream_close(args[0]);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream___exit___obj, 4, 4, mp_stream___exit__);
// Re-implemented from obj.c, not yet available in dynruntime.h.
mp_obj_t mp_identity(mp_obj_t self) {
return self;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity);
mp_map_elem_t deflateio_locals_dict_table[7];
STATIC MP_DEFINE_CONST_DICT(deflateio_locals_dict, deflateio_locals_dict_table);
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
deflateio_type.base.type = mp_fun_table.type_type;
deflateio_type.name = MP_QSTR_DeflateIO;
MP_OBJ_TYPE_SET_SLOT(&deflateio_type, make_new, &deflateio_make_new, 0);
MP_OBJ_TYPE_SET_SLOT(&deflateio_type, protocol, &deflateio_stream_p, 1);
deflateio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) };
deflateio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) };
deflateio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) };
deflateio_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_OBJ_FROM_PTR(&mp_stream_write_obj) };
deflateio_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&mp_stream_close_obj) };
deflateio_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR___enter__), MP_OBJ_FROM_PTR(&mp_identity_obj) };
deflateio_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR___exit__), MP_OBJ_FROM_PTR(&mp_stream___exit___obj) };
MP_OBJ_TYPE_SET_SLOT(&deflateio_type, locals_dict, (void*)&deflateio_locals_dict, 2);
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_deflate));
mp_store_global(MP_QSTR_DeflateIO, MP_OBJ_FROM_PTR(&deflateio_type));
mp_store_global(MP_QSTR_RAW, MP_OBJ_NEW_SMALL_INT(DEFLATEIO_FORMAT_RAW));
mp_store_global(MP_QSTR_ZLIB, MP_OBJ_NEW_SMALL_INT(DEFLATEIO_FORMAT_ZLIB));
mp_store_global(MP_QSTR_GZIP, MP_OBJ_NEW_SMALL_INT(DEFLATEIO_FORMAT_GZIP));
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -88,7 +88,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
// This must be first, it sets up the globals dict and other things // This must be first, it sets up the globals dict and other things
MP_DYNRUNTIME_INIT_ENTRY MP_DYNRUNTIME_INIT_ENTRY
// Messages can be printed as usually // Messages can be printed as usual
mp_printf(&mp_plat_print, "initialising module self=%p\n", self); mp_printf(&mp_plat_print, "initialising module self=%p\n", self);
// Make the functions available in the module's namespace // Make the functions available in the module's namespace

View File

@ -1,5 +1,7 @@
# This Python code will be merged with the C code in main.c # This Python code will be merged with the C code in main.c
# ruff: noqa: F821 - this file is evaluated with C-defined names in scope
import array import array

View File

@ -0,0 +1,14 @@
# Location of top-level MicroPython directory
MPY_DIR = ../../..
# Name of module
MOD = features4
# Source files (.c or .py)
SRC = features4.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64
# Include to get the rules for compiling and linking the module
include $(MPY_DIR)/py/dynruntime.mk

View File

@ -0,0 +1,73 @@
/*
This example extends on features0 but demonstrates how to define a class.
The Factorial class constructor takes an integer, and then the calculate
method can be called to get the factorial.
>>> import features4
>>> f = features4.Factorial(4)
>>> f.calculate()
24
*/
// Include the header file to get access to the MicroPython API
#include "py/dynruntime.h"
// This is type(Factorial)
mp_obj_full_type_t mp_type_factorial;
// This is the internal state of a Factorial instance.
typedef struct {
mp_obj_base_t base;
mp_int_t n;
} mp_obj_factorial_t;
// Essentially Factorial.__new__ (but also kind of __init__).
// Takes a single argument (the number to find the factorial of)
STATIC mp_obj_t factorial_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
mp_obj_factorial_t *o = mp_obj_malloc(mp_obj_factorial_t, type);
o->n = mp_obj_get_int(args_in[0]);
return MP_OBJ_FROM_PTR(o);
}
STATIC mp_int_t factorial_helper(mp_int_t x) {
if (x == 0) {
return 1;
}
return x * factorial_helper(x - 1);
}
// Implements Factorial.calculate()
STATIC mp_obj_t factorial_calculate(mp_obj_t self_in) {
mp_obj_factorial_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(factorial_helper(self->n));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_calculate_obj, factorial_calculate);
// Locals dict for the Factorial type (will have a single method, calculate,
// added in mpy_init).
mp_map_elem_t factorial_locals_dict_table[1];
STATIC MP_DEFINE_CONST_DICT(factorial_locals_dict, factorial_locals_dict_table);
// This is the entry point and is called when the module is imported
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
// This must be first, it sets up the globals dict and other things
MP_DYNRUNTIME_INIT_ENTRY
// Initialise the type.
mp_type_factorial.base.type = (void*)&mp_type_type;
mp_type_factorial.flags = MP_TYPE_FLAG_NONE;
mp_type_factorial.name = MP_QSTR_Factorial;
MP_OBJ_TYPE_SET_SLOT(&mp_type_factorial, make_new, factorial_make_new, 0);
factorial_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_calculate), MP_OBJ_FROM_PTR(&factorial_calculate_obj) };
MP_OBJ_TYPE_SET_SLOT(&mp_type_factorial, locals_dict, (void*)&factorial_locals_dict, 1);
// Make the Factorial type available on the module.
mp_store_global(MP_QSTR_Factorial, MP_OBJ_FROM_PTR(&mp_type_factorial));
// This must be last, it restores the globals dict
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -1,11 +1,11 @@
# Location of top-level MicroPython directory # Location of top-level MicroPython directory
MPY_DIR = ../../.. MPY_DIR = ../../..
# Name of module (different to built-in urandom so it can coexist) # Name of module (different to built-in heapq so it can coexist)
MOD = urandom_$(ARCH) MOD = heapq_$(ARCH)
# Source files (.c or .py) # Source files (.c or .py)
SRC = urandom.c SRC = heapq.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64 ARCH = x64

View File

@ -0,0 +1,16 @@
#define MICROPY_PY_HEAPQ (1)
#include "py/dynruntime.h"
#include "extmod/modheapq.c"
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_heapq));
mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_heapq_heappush_obj));
mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_heapq_heappop_obj));
mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_heapq_heapify_obj));
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -1,11 +1,11 @@
# Location of top-level MicroPython directory # Location of top-level MicroPython directory
MPY_DIR = ../../.. MPY_DIR = ../../..
# Name of module (different to built-in uheapq so it can coexist) # Name of module (different to built-in random so it can coexist)
MOD = uheapq_$(ARCH) MOD = random_$(ARCH)
# Source files (.c or .py) # Source files (.c or .py)
SRC = uheapq.c SRC = random.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64 ARCH = x64

View File

@ -0,0 +1,33 @@
#define MICROPY_PY_RANDOM (1)
#define MICROPY_PY_RANDOM_EXTRA_FUNCS (1)
#include "py/dynruntime.h"
// Dynamic native modules don't support a data section so these must go in the BSS
uint32_t yasmarang_pad, yasmarang_n, yasmarang_d;
uint8_t yasmarang_dat;
#include "extmod/modrandom.c"
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
yasmarang_pad = 0xeda4baba;
yasmarang_n = 69;
yasmarang_d = 233;
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_random));
mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_random_getrandbits_obj));
mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_random_seed_obj));
#if MICROPY_PY_RANDOM_EXTRA_FUNCS
mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_random_randrange_obj));
mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_random_randint_obj));
mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_random_choice_obj));
#if MICROPY_PY_BUILTINS_FLOAT
mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_random_random_obj));
mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_random_uniform_obj));
#endif
#endif
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -1,11 +1,11 @@
# Location of top-level MicroPython directory # Location of top-level MicroPython directory
MPY_DIR = ../../.. MPY_DIR = ../../..
# Name of module (different to built-in ure so it can coexist) # Name of module (different to built-in re so it can coexist)
MOD = ure_$(ARCH) MOD = re_$(ARCH)
# Source files (.c or .py) # Source files (.c or .py)
SRC = ure.c SRC = re.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64 ARCH = x64

View File

@ -1,8 +1,8 @@
#define MICROPY_STACK_CHECK (1) #define MICROPY_STACK_CHECK (1)
#define MICROPY_PY_URE (1) #define MICROPY_PY_RE (1)
#define MICROPY_PY_URE_MATCH_GROUPS (1) #define MICROPY_PY_RE_MATCH_GROUPS (1)
#define MICROPY_PY_URE_MATCH_SPAN_START_END (1) #define MICROPY_PY_RE_MATCH_SPAN_START_END (1)
#define MICROPY_PY_URE_SUB (0) // requires vstr interface #define MICROPY_PY_RE_SUB (0) // requires vstr interface
#include <alloca.h> #include <alloca.h>
#include "py/dynruntime.h" #include "py/dynruntime.h"
@ -35,7 +35,7 @@ void *memmove(void *dest, const void *src, size_t n) {
mp_obj_full_type_t match_type; mp_obj_full_type_t match_type;
mp_obj_full_type_t re_type; mp_obj_full_type_t re_type;
#include "extmod/modure.c" #include "extmod/modre.c"
mp_map_elem_t match_locals_dict_table[5]; mp_map_elem_t match_locals_dict_table[5];
STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table);
@ -63,7 +63,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
MP_OBJ_TYPE_SET_SLOT(&match_type, locals_dict, (void*)&match_locals_dict, 1); MP_OBJ_TYPE_SET_SLOT(&match_type, locals_dict, (void*)&match_locals_dict, 1);
re_type.base.type = (void*)&mp_fun_table.type_type; re_type.base.type = (void*)&mp_fun_table.type_type;
re_type.name = MP_QSTR_ure; re_type.name = MP_QSTR_re;
MP_OBJ_TYPE_SET_SLOT(&re_type, print, re_print, 0); MP_OBJ_TYPE_SET_SLOT(&re_type, print, re_print, 0);
re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) };
re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) };

View File

@ -1,16 +0,0 @@
#define MICROPY_PY_UHEAPQ (1)
#include "py/dynruntime.h"
#include "extmod/moduheapq.c"
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uheapq));
mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_uheapq_heappush_obj));
mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_uheapq_heappop_obj));
mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_uheapq_heapify_obj));
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -1,33 +0,0 @@
#define MICROPY_PY_URANDOM (1)
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
#include "py/dynruntime.h"
// Dynamic native modules don't support a data section so these must go in the BSS
uint32_t yasmarang_pad, yasmarang_n, yasmarang_d;
uint8_t yasmarang_dat;
#include "extmod/modurandom.c"
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
yasmarang_pad = 0xeda4baba;
yasmarang_n = 69;
yasmarang_d = 233;
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_urandom));
mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_urandom_getrandbits_obj));
mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_urandom_seed_obj));
#if MICROPY_PY_URANDOM_EXTRA_FUNCS
mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_urandom_randrange_obj));
mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_urandom_randint_obj));
mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_urandom_choice_obj));
#if MICROPY_PY_BUILTINS_FLOAT
mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_urandom_random_obj));
mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_urandom_uniform_obj));
#endif
#endif
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -1,35 +0,0 @@
#define MICROPY_PY_UZLIB (1)
#include "py/dynruntime.h"
#if !defined(__linux__)
void *memset(void *s, int c, size_t n) {
return mp_fun_table.memset_(s, c, n);
}
#endif
mp_obj_full_type_t decompio_type;
#include "extmod/moduzlib.c"
mp_map_elem_t decompio_locals_dict_table[3];
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
decompio_type.base.type = mp_fun_table.type_type;
decompio_type.name = MP_QSTR_DecompIO;
MP_OBJ_TYPE_SET_SLOT(&decompio_type, make_new, &decompio_make_new, 0);
MP_OBJ_TYPE_SET_SLOT(&decompio_type, protocol, &decompio_stream_p, 1);
decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) };
decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) };
decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) };
MP_OBJ_TYPE_SET_SLOT(&decompio_type, locals_dict, (void*)&decompio_locals_dict, 2);
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib));
mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj));
mp_store_global(MP_QSTR_DecompIO, MP_OBJ_FROM_PTR(&decompio_type));
MP_DYNRUNTIME_INIT_EXIT
}

View File

@ -68,7 +68,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
locals_dict, &example_Timer_locals_dict locals_dict, &example_Timer_locals_dict
); );
// Define all properties of the module. // Define all attributes of the module.
// Table entries are key/value pairs of the attribute name (a string) // Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference. // and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be // All identifiers and strings are written as MP_QSTR_xxx and will be

View File

@ -1,9 +1,8 @@
EXAMPLE_MOD_DIR := $(USERMOD_DIR) CEXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD. # Add all C files to SRC_USERMOD.
SRC_USERMOD += $(EXAMPLE_MOD_DIR)/examplemodule.c SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/examplemodule.c
# We can add our module folder to include paths if needed # We can add our module folder to include paths if needed
# This is not actually needed in this example. # This is not actually needed in this example.
CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR) CFLAGS_USERMOD += -I$(CEXAMPLE_MOD_DIR)
CEXAMPLE_MOD_DIR := $(USERMOD_DIR)

View File

@ -4,7 +4,7 @@
// See example.cpp for the definition. // See example.cpp for the definition.
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc); STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc);
// Define all properties of the module. // Define all attributes of the module.
// Table entries are key/value pairs of the attribute name (a string) // Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference. // and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be // All identifiers and strings are written as MP_QSTR_xxx and will be

View File

@ -0,0 +1 @@
This is an example of a user C module that includes subpackages.

View File

@ -0,0 +1,19 @@
# Create an INTERFACE library for our C module.
add_library(usermod_subpackage_example INTERFACE)
# Add our source files to the lib
target_sources(usermod_subpackage_example INTERFACE
${CMAKE_CURRENT_LIST_DIR}/examplemodule.c
)
# Add the current directory as an include directory.
target_include_directories(usermod_subpackage_example INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
target_compile_definitions(usermod_subpackage_example INTERFACE
MICROPY_MODULE_BUILTIN_SUBPACKAGES=1
)
# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_subpackage_example)

View File

@ -0,0 +1,10 @@
SUBPACKAGE_EXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(SUBPACKAGE_EXAMPLE_MOD_DIR)/modexamplepackage.c
# We can add our module folder to include paths if needed
# This is not actually needed in this example.
CFLAGS_USERMOD += -I$(SUBPACKAGE_EXAMPLE_MOD_DIR) -DMICROPY_MODULE_BUILTIN_SUBPACKAGES=1
QSTR_DEFS += $(SUBPACKAGE_EXAMPLE_MOD_DIR)/qstrdefsexamplepackage.h

View File

@ -0,0 +1,84 @@
// Include MicroPython API.
#include "py/runtime.h"
// Define example_package.foo.bar.f()
STATIC mp_obj_t example_package_foo_bar_f(void) {
mp_printf(&mp_plat_print, "example_package.foo.bar.f\n");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(example_package_foo_bar_f_obj, example_package_foo_bar_f);
// Define all attributes of the second-level sub-package (example_package.foo.bar).
STATIC const mp_rom_map_elem_t example_package_foo_bar_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package_dot_foo_dot_bar) },
{ MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_foo_bar_f_obj) },
};
STATIC MP_DEFINE_CONST_DICT(example_package_foo_bar_globals, example_package_foo_bar_globals_table);
// Define example_package.foo.bar module object.
const mp_obj_module_t example_package_foo_bar_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&example_package_foo_bar_globals,
};
// Define example_package.foo.f()
STATIC mp_obj_t example_package_foo_f(void) {
mp_printf(&mp_plat_print, "example_package.foo.f\n");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(example_package_foo_f_obj, example_package_foo_f);
// Define all attributes of the first-level sub-package (example_package.foo).
STATIC const mp_rom_map_elem_t example_package_foo_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package_dot_foo) },
{ MP_ROM_QSTR(MP_QSTR_bar), MP_ROM_PTR(&example_package_foo_bar_user_cmodule) },
{ MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_foo_f_obj) },
};
STATIC MP_DEFINE_CONST_DICT(example_package_foo_globals, example_package_foo_globals_table);
// Define example_package.foo module object.
const mp_obj_module_t example_package_foo_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&example_package_foo_globals,
};
// Define example_package.f()
STATIC mp_obj_t example_package_f(void) {
mp_printf(&mp_plat_print, "example_package.f\n");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(example_package_f_obj, example_package_f);
STATIC mp_obj_t example_package___init__(void) {
if (!MP_STATE_VM(example_package_initialised)) {
// __init__ for builtins is called each time the module is imported,
// so ensure that initialisation only happens once.
MP_STATE_VM(example_package_initialised) = true;
mp_printf(&mp_plat_print, "example_package.__init__\n");
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(example_package___init___obj, example_package___init__);
// The "initialised" state is stored on mp_state so that it is cleared on soft
// reset.
MP_REGISTER_ROOT_POINTER(int example_package_initialised);
// Define all attributes of the top-level package (example_package).
STATIC const mp_rom_map_elem_t example_package_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package) },
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&example_package___init___obj) },
{ MP_ROM_QSTR(MP_QSTR_foo), MP_ROM_PTR(&example_package_foo_user_cmodule) },
{ MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_f_obj) },
};
STATIC MP_DEFINE_CONST_DICT(example_package_globals, example_package_globals_table);
// Define module object.
const mp_obj_module_t example_package_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&example_package_globals,
};
// Register the module to make it available in Python.
// Note: subpackages should not be registered with MP_REGISTER_MODULE.
MP_REGISTER_MODULE(MP_QSTR_example_package, example_package_user_cmodule);

View File

@ -0,0 +1,2 @@
Q(example_package.foo)
Q(example_package.foo.bar)

View File

@ -1,20 +1,20 @@
# This makefile fragment adds the source code files for the core extmod modules # This makefile fragment adds the source code files for the core extmod modules
# and provides rules to build 3rd-party components for extmod modules. # and provides rules to build 3rd-party components for extmod modules.
# CIRCUITPY-CHANGE: many extmod modules removed
SRC_EXTMOD_C += \ SRC_EXTMOD_C += \
extmod/moduasyncio.c \ extmod/modasyncio.c \
extmod/modubinascii.c \ extmod/modbinascii.c \
extmod/modhashlib.c \
extmod/modheapq.c \
extmod/modjson.c \
extmod/modos.c \
extmod/modplatform.c\
extmod/modrandom.c \
extmod/modre.c \
extmod/modselect.c \
extmod/moductypes.c \ extmod/moductypes.c \
extmod/moduhashlib.c \ extmod/modzlib.c \
extmod/moduheapq.c \
extmod/modujson.c \
extmod/moduos.c \
extmod/moduplatform.c\
extmod/modurandom.c \
extmod/modure.c \
extmod/moduselect.c \
extmod/moduzlib.c \
extmod/utime_mphal.c \
extmod/vfs.c \ extmod/vfs.c \
extmod/vfs_blockdev.c \ extmod/vfs_blockdev.c \
extmod/vfs_fat.c \ extmod/vfs_fat.c \
@ -81,10 +81,9 @@ endif
################################################################################ ################################################################################
# ussl # ussl
ifeq ($(MICROPY_PY_USSL),1) ifeq ($(MICROPY_PY_SSL),1)
CFLAGS_EXTMOD += -DMICROPY_PY_USSL=1 CFLAGS_EXTMOD += -DMICROPY_PY_SSL=1
ifeq ($(MICROPY_SSL_AXTLS),1) ifeq ($(MICROPY_SSL_AXTLS),1)
CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include
AXTLS_DIR = lib/axtls AXTLS_DIR = lib/axtls
GIT_SUBMODULES += $(AXTLS_DIR) GIT_SUBMODULES += $(AXTLS_DIR)
CFLAGS_EXTMOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include CFLAGS_EXTMOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include
@ -146,7 +145,6 @@ SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\
md4.c \ md4.c \
md5.c \ md5.c \
md.c \ md.c \
md_wrap.c \
oid.c \ oid.c \
padlock.c \ padlock.c \
pem.c \ pem.c \
@ -171,9 +169,11 @@ SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\
ssl_cli.c \ ssl_cli.c \
ssl_cookie.c \ ssl_cookie.c \
ssl_srv.c \ ssl_srv.c \
ssl_msg.c \
ssl_ticket.c \ ssl_ticket.c \
ssl_tls.c \ ssl_tls.c \
timing.c \ timing.c \
constant_time.c \
x509.c \ x509.c \
x509_create.c \ x509_create.c \
x509_crl.c \ x509_crl.c \
@ -267,7 +267,7 @@ SRC_THIRDPARTY_C += $(addprefix $(BTREE_DIR)/,\
CFLAGS_EXTMOD += -DMICROPY_PY_BTREE=1 CFLAGS_EXTMOD += -DMICROPY_PY_BTREE=1
# we need to suppress certain warnings to get berkeley-db to compile cleanly # we need to suppress certain warnings to get berkeley-db to compile cleanly
# and we have separate BTREE_DEFS so the definitions don't interfere with other source code # and we have separate BTREE_DEFS so the definitions don't interfere with other source code
$(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS) $(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter -Wno-deprecated-non-prototype -Wno-unknown-warning-option $(BTREE_DEFS)
$(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS) $(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS)
endif endif
@ -311,8 +311,51 @@ SRC_THIRDPARTY_C += $(addprefix $(WIZNET5K_DIR)/,\
Internet/DHCP/dhcp.c \ Internet/DHCP/dhcp.c \
) )
endif endif
endif # MICROPY_PY_NETWORK_WIZNET5K
ifeq ($(MICROPY_PY_NETWORK_ESP_HOSTED),1)
ESP_HOSTED_DIR = drivers/esp-hosted
PROTOBUF_C_DIR = lib/protobuf-c
PROTOC ?= protoc-c
GIT_SUBMODULES += $(PROTOBUF_C_DIR)
CFLAGS += -DMICROPY_PY_NETWORK_ESP_HOSTED=1
CFLAGS_EXTMOD += -DMICROPY_PY_NETWORK_ESP_HOSTED=1
INC += -I$(TOP)/$(ESP_HOSTED_DIR)
ESP_HOSTED_SRC_C = $(addprefix $(ESP_HOSTED_DIR)/,\
esp_hosted_wifi.c \
esp_hosted_netif.c \
esp_hosted_hal.c \
)
ifeq ($(MICROPY_PY_BLUETOOTH),1)
ESP_HOSTED_SRC_C += $(ESP_HOSTED_DIR)/esp_hosted_bthci.c
endif endif
# Include the protobuf-c support functions
ESP_HOSTED_SRC_C += $(addprefix $(PROTOBUF_C_DIR)/,\
protobuf-c/protobuf-c.c \
)
$(BUILD)/$(PROTOBUF_C_DIR)/%.o: CFLAGS += -Wno-unused-but-set-variable
# Generate esp_hosted-pb-c.c|h from esp_hosted.proto
PROTO_GEN_SRC = $(BUILD)/extmod/esp_hosted.pb-c.c
ESP_HOSTED_SRC_C += $(PROTO_GEN_SRC)
$(PROTO_GEN_SRC): $(TOP)/$(ESP_HOSTED_DIR)/esp_hosted.proto
$(PROTOC) --proto_path=$(dir $<) --c_out=$(dir $@) $<
# Scope the protobuf include paths to the esp_hosted source files, only
ESP_HOSTED_OBJS = $(addprefix $(BUILD)/, $(ESP_HOSTED_SRC_C:.c=.o))
$(ESP_HOSTED_OBJS): $(PROTO_GEN_SRC)
$(ESP_HOSTED_OBJS): CFLAGS += -I$(dir $(PROTO_GEN_SRC)) -I$(TOP)/$(PROTOBUF_C_DIR)
DRIVERS_SRC_C += $(ESP_HOSTED_SRC_C)
endif # MICROPY_PY_NETWORK_ESP_HOSTED
################################################################################ ################################################################################
# bluetooth # bluetooth

View File

@ -32,17 +32,17 @@
#include <stddef.h> #include <stddef.h>
#include "py/runtime.h" #include "py/runtime.h"
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_os_dupterm_obj);
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream); bool mp_os_dupterm_is_builtin_stream(mp_const_obj_t stream);
void mp_uos_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached); void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached);
uintptr_t mp_uos_dupterm_poll(uintptr_t poll_flags); uintptr_t mp_os_dupterm_poll(uintptr_t poll_flags);
int mp_uos_dupterm_rx_chr(void); int mp_os_dupterm_rx_chr(void);
void mp_uos_dupterm_tx_strn(const char *str, size_t len); void mp_os_dupterm_tx_strn(const char *str, size_t len);
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc); void mp_os_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc);
#else #else
#define mp_uos_dupterm_tx_strn(s, l) #define mp_os_dupterm_tx_strn(s, l)
#endif #endif
#endif // MICROPY_INCLUDED_EXTMOD_MISC_H #endif // MICROPY_INCLUDED_EXTMOD_MISC_H

View File

@ -29,7 +29,7 @@
#include "py/pairheap.h" #include "py/pairheap.h"
#include "py/mphal.h" #include "py/mphal.h"
#if MICROPY_PY_UASYNCIO #if MICROPY_PY_ASYNCIO
#if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__)) #if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__))
#include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/__init__.h"
@ -68,14 +68,14 @@ STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, si
// Ticks for task ordering in pairing heap // Ticks for task ordering in pairing heap
STATIC mp_obj_t ticks(void) { STATIC mp_obj_t ticks(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)); return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_TIME_TICKS_PERIOD - 1));
} }
STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) { STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) {
mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in); mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in);
mp_uint_t t1 = MP_OBJ_SMALL_INT_VALUE(t1_in); mp_uint_t t1 = MP_OBJ_SMALL_INT_VALUE(t1_in);
mp_int_t diff = ((t1 - t0 + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)) mp_int_t diff = ((t1 - t0 + MICROPY_PY_TIME_TICKS_PERIOD / 2) & (MICROPY_PY_TIME_TICKS_PERIOD - 1))
- MICROPY_PY_UTIME_TICKS_PERIOD / 2; - MICROPY_PY_TIME_TICKS_PERIOD / 2;
return diff; return diff;
} }
@ -146,7 +146,7 @@ STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) }, { MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
// CIRCUITPYTHON: Remove these in CircuitPython 10.0.0 // CIRCUITPY-CHANGE: Remove these in CircuitPython 10.0.0
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) }, { MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) },
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) }, { MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) },
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) }, { MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) },
@ -164,8 +164,8 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
/******************************************************************************/ /******************************************************************************/
// Task class // Task class
// This is the core uasyncio context with cur_task, _task_queue and CancelledError. // This is the core asyncio context with cur_task, _task_queue and CancelledError.
STATIC mp_obj_t uasyncio_context = MP_OBJ_NULL; STATIC mp_obj_t asyncio_context = MP_OBJ_NULL;
STATIC mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_arg_check_num(n_args, n_kw, 1, 2, false);
@ -177,7 +177,7 @@ STATIC mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
self->state = TASK_STATE_RUNNING_NOT_WAITED_ON; self->state = TASK_STATE_RUNNING_NOT_WAITED_ON;
self->ph_key = MP_OBJ_NEW_SMALL_INT(0); self->ph_key = MP_OBJ_NEW_SMALL_INT(0);
if (n_args == 2) { if (n_args == 2) {
uasyncio_context = args[1]; asyncio_context = args[1];
} }
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
@ -195,7 +195,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
return mp_const_false; return mp_const_false;
} }
// Can't cancel self (not supported yet). // Can't cancel self (not supported yet).
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); mp_obj_t cur_task = mp_obj_dict_get(asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
if (self_in == cur_task) { if (self_in == cur_task) {
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't cancel self")); mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't cancel self"));
} }
@ -204,7 +204,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
self = MP_OBJ_TO_PTR(self->data); self = MP_OBJ_TO_PTR(self->data);
} }
mp_obj_t _task_queue = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__task_queue)); mp_obj_t _task_queue = mp_obj_dict_get(asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__task_queue));
// Reschedule Task as a cancelled task. // Reschedule Task as a cancelled task.
mp_obj_t dest[3]; mp_obj_t dest[3];
@ -227,13 +227,13 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
task_queue_push(2, dest); task_queue_push(2, dest);
} }
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError)); self->data = mp_obj_dict_get(asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
return mp_const_true; return mp_const_true;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel); STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
// CIRCUITPY provides __await__(). // CIRCUITPY-CHANGE: CircuitPython provides __await__().
STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
STATIC mp_obj_t task_await(mp_obj_t self_in) { STATIC mp_obj_t task_await(mp_obj_t self_in) {
@ -303,7 +303,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
} }
} else { } else {
// Put calling task on waiting queue. // Put calling task on waiting queue.
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); mp_obj_t cur_task = mp_obj_dict_get(asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
mp_obj_t args[2] = { self->state, cur_task }; mp_obj_t args[2] = { self->state, cur_task };
task_queue_push(2, args); task_queue_push(2, args);
// Set calling task's data to this task that it waits on, to double-link it. // Set calling task's data to this task that it waits on, to double-link it.
@ -327,20 +327,20 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
); );
/******************************************************************************/ /******************************************************************************/
// C-level uasyncio module // C-level asyncio module
STATIC const mp_rom_map_elem_t mp_module_uasyncio_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_asyncio_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__uasyncio) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__asyncio) },
{ MP_ROM_QSTR(MP_QSTR_TaskQueue), MP_ROM_PTR(&task_queue_type) }, { MP_ROM_QSTR(MP_QSTR_TaskQueue), MP_ROM_PTR(&task_queue_type) },
{ MP_ROM_QSTR(MP_QSTR_Task), MP_ROM_PTR(&task_type) }, { MP_ROM_QSTR(MP_QSTR_Task), MP_ROM_PTR(&task_type) },
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_uasyncio_globals, mp_module_uasyncio_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_asyncio_globals, mp_module_asyncio_globals_table);
const mp_obj_module_t mp_module_uasyncio = { const mp_obj_module_t mp_module_asyncio = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals, .globals = (mp_obj_dict_t *)&mp_module_asyncio_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio); MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_asyncio);
#endif // MICROPY_PY_UASYNCIO #endif // MICROPY_PY_ASYNCIO

View File

@ -32,9 +32,7 @@
#include "py/binary.h" #include "py/binary.h"
#include "py/objstr.h" #include "py/objstr.h"
#include "lib/uzlib/tinf.h" #if MICROPY_PY_BINASCII
#if MICROPY_PY_UBINASCII
static void check_not_unicode(const mp_obj_t arg) { static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT #if MICROPY_CPYTHON_COMPAT
@ -48,7 +46,6 @@ static void check_not_unicode(const mp_obj_t arg) {
STATIC mp_obj_t bytes_hex_as_bytes(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t bytes_hex_as_bytes(size_t n_args, const mp_obj_t *args) {
return mp_obj_bytes_hex(n_args, args, &mp_type_bytes); return mp_obj_bytes_hex(n_args, args, &mp_type_bytes);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_hex_as_bytes_obj, 1, 2, bytes_hex_as_bytes); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_hex_as_bytes_obj, 1, 2, bytes_hex_as_bytes);
STATIC mp_obj_t bytes_fromhex_bytes(mp_obj_t data) { STATIC mp_obj_t bytes_fromhex_bytes(mp_obj_t data) {
@ -82,7 +79,7 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
byte *in = bufinfo.buf; byte *in = bufinfo.buf;
vstr_t vstr; vstr_t vstr;
vstr_init(&vstr, (bufinfo.len / 4) * 3 + 1); // Potentially over-allocate vstr_init(&vstr, (bufinfo.len * 3) / 4 + 1); // Potentially over-allocate
byte *out = (byte *)vstr.buf; byte *out = (byte *)vstr.buf;
uint shift = 0; uint shift = 0;
@ -128,7 +125,7 @@ STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args,
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint8_t newline = args[ARG_newline].u_bool; uint8_t newline = args[ARG_newline].u_bool;
// CIRCUITPY // CIRCUITPY-CHANGE
check_not_unicode(pos_args[0]); check_not_unicode(pos_args[0]);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ);
@ -183,46 +180,13 @@ STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args,
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64);
// CIRCUITPY uses a self-contained implementation of CRC32, // CIRCUITPY-CHANGE: no deflate
// instead of depending on uzlib, like MicroPython. #if MICROPY_PY_BINASCII_CRC32
#include "lib/uzlib/uzlib.h"
/*
* CRC32 checksum
*
* Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#if MICROPY_PY_UBINASCII_CRC32
STATIC mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
// CIRCUITPY // CIRCUITPY-CHANGE
check_not_unicode(args[0]); check_not_unicode(args[0]);
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0; uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0;
@ -233,25 +197,26 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_bin
#endif #endif
STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubinascii) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_binascii) },
#if MICROPY_PY_BUILTINS_BYTES_HEX #if MICROPY_PY_BUILTINS_BYTES_HEX
{ MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&bytes_hex_as_bytes_obj) }, { MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&bytes_hex_as_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&bytes_fromhex_obj) }, { MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&bytes_fromhex_obj) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) }, { MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) },
{ MP_ROM_QSTR(MP_QSTR_b2a_base64), MP_ROM_PTR(&mod_binascii_b2a_base64_obj) }, { MP_ROM_QSTR(MP_QSTR_b2a_base64), MP_ROM_PTR(&mod_binascii_b2a_base64_obj) },
#if MICROPY_PY_UBINASCII_CRC32 // CIRCUITPY-CHANGE: no deflate
#if MICROPY_PY_BINASCII_CRC32
{ MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_binascii_crc32_obj) }, { MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_binascii_crc32_obj) },
#endif #endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table);
const mp_obj_module_t mp_module_ubinascii = { const mp_obj_module_t mp_module_binascii = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals, .globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_binascii, mp_module_binascii);
#endif // MICROPY_PY_UBINASCII #endif // MICROPY_PY_BINASCII

415
extmod/moddeflate.c Normal file
View File

@ -0,0 +1,415 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2023 Jim Mussared
*
* Based on extmod/modzlib.c
* Copyright (c) 2014-2016 Paul Sokolovsky
* Copyright (c) 2021-2023 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
#if MICROPY_PY_DEFLATE
#include "lib/uzlib/uzlib.h"
#if 0 // print debugging info
#define DEBUG_printf DEBUG_printf
#else // don't print debugging info
#define DEBUG_printf(...) (void)0
#endif
typedef enum {
DEFLATEIO_FORMAT_MIN = 0,
DEFLATEIO_FORMAT_AUTO = DEFLATEIO_FORMAT_MIN, // Read mode this means auto-detect zlib/gzip, write mode this means RAW.
DEFLATEIO_FORMAT_RAW = 1,
DEFLATEIO_FORMAT_ZLIB = 2,
DEFLATEIO_FORMAT_GZIP = 3,
DEFLATEIO_FORMAT_MAX = DEFLATEIO_FORMAT_GZIP,
} deflateio_format_t;
// This is used when the wbits is unset in the DeflateIO constructor. Default
// to the smallest window size (faster compression, less RAM usage, etc).
const int DEFLATEIO_DEFAULT_WBITS = 8;
typedef struct {
void *window;
uzlib_uncomp_t decomp;
bool eof;
} mp_obj_deflateio_read_t;
#if MICROPY_PY_DEFLATE_COMPRESS
typedef struct {
void *window;
size_t input_len;
uint32_t input_checksum;
uzlib_lz77_state_t lz77;
} mp_obj_deflateio_write_t;
#endif
typedef struct {
mp_obj_base_t base;
mp_obj_t stream;
uint8_t format : 2;
uint8_t window_bits : 4;
bool close : 1;
mp_obj_deflateio_read_t *read;
#if MICROPY_PY_DEFLATE_COMPRESS
mp_obj_deflateio_write_t *write;
#endif
} mp_obj_deflateio_t;
STATIC int deflateio_read_stream(void *data) {
mp_obj_deflateio_t *self = data;
const mp_stream_p_t *stream = mp_get_stream(self->stream);
int err;
byte c;
mp_uint_t out_sz = stream->read(self->stream, &c, 1, &err);
if (out_sz == MP_STREAM_ERROR) {
mp_raise_OSError(err);
}
if (out_sz == 0) {
mp_raise_type(&mp_type_EOFError);
}
return c;
}
STATIC bool deflateio_init_read(mp_obj_deflateio_t *self) {
if (self->read) {
return true;
}
mp_get_stream_raise(self->stream, MP_STREAM_OP_READ);
self->read = m_new_obj(mp_obj_deflateio_read_t);
memset(&self->read->decomp, 0, sizeof(self->read->decomp));
self->read->decomp.source_read_data = self;
self->read->decomp.source_read_cb = deflateio_read_stream;
self->read->eof = false;
// Don't modify self->window_bits as it may also be used for write.
int wbits = self->window_bits;
if (self->format == DEFLATEIO_FORMAT_RAW) {
if (wbits == 0) {
// The docs recommends always setting wbits explicitly when using
// RAW, but we still allow a default.
wbits = DEFLATEIO_DEFAULT_WBITS;
}
} else {
// Parse the header if we're in NONE/ZLIB/GZIP modes.
int header_wbits;
int header_type = uzlib_parse_zlib_gzip_header(&self->read->decomp, &header_wbits);
if (header_type < 0) {
// Stream header was invalid.
return false;
}
if ((self->format == DEFLATEIO_FORMAT_ZLIB && header_type != UZLIB_HEADER_ZLIB) || (self->format == DEFLATEIO_FORMAT_GZIP && header_type != UZLIB_HEADER_GZIP)) {
// Not what we expected.
return false;
}
// header_wbits will either be 15 (gzip) or 8-15 (zlib).
if (wbits == 0 || header_wbits < wbits) {
// If the header specified something lower, then use that instead.
// No point doing a bigger allocation than we need to.
wbits = header_wbits;
}
}
size_t window_len = 1 << wbits;
self->read->window = m_new(uint8_t, window_len);
uzlib_uncompress_init(&self->read->decomp, self->read->window, window_len);
return true;
}
#if MICROPY_PY_DEFLATE_COMPRESS
STATIC void deflateio_out_byte(void *data, uint8_t b) {
mp_obj_deflateio_t *self = data;
const mp_stream_p_t *stream = mp_get_stream(self->stream);
int err;
mp_uint_t ret = stream->write(self->stream, &b, 1, &err);
if (ret == MP_STREAM_ERROR) {
mp_raise_OSError(err);
}
}
STATIC bool deflateio_init_write(mp_obj_deflateio_t *self) {
if (self->write) {
return true;
}
const mp_stream_p_t *stream = mp_get_stream_raise(self->stream, MP_STREAM_OP_WRITE);
self->write = m_new_obj(mp_obj_deflateio_write_t);
self->write->input_len = 0;
int wbits = self->window_bits;
if (wbits == 0) {
// Same default wbits for all formats.
wbits = DEFLATEIO_DEFAULT_WBITS;
}
size_t window_len = 1 << wbits;
self->write->window = m_new(uint8_t, window_len);
uzlib_lz77_init(&self->write->lz77, self->write->window, window_len);
self->write->lz77.dest_write_data = self;
self->write->lz77.dest_write_cb = deflateio_out_byte;
// Write header if needed.
mp_uint_t ret = 0;
int err;
if (self->format == DEFLATEIO_FORMAT_ZLIB) {
// -----CMF------ ----------FLG---------------
// CINFO(5) CM(3) FLEVEL(2) FDICT(1) FCHECK(5)
uint8_t buf[] = { 0x08, 0x80 }; // CM=2 (deflate), FLEVEL=2 (default), FDICT=0 (no dictionary)
buf[0] |= MAX(wbits - 8, 1) << 4; // base-2 logarithm of the LZ77 window size, minus eight.
buf[1] |= 31 - ((buf[0] * 256 + buf[1]) % 31); // (CMF*256 + FLG) % 31 == 0.
ret = stream->write(self->stream, buf, sizeof(buf), &err);
self->write->input_checksum = 1; // ADLER32
} else if (self->format == DEFLATEIO_FORMAT_GZIP) {
// ID1(8) ID2(8) CM(8) ---FLG--- MTIME(32) XFL(8) OS(8)
// FLG: x x x FCOMMENT FNAME FEXTRA FHCRC FTEXT
uint8_t buf[] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03 }; // MTIME=0, XFL=4 (fastest), OS=3 (unix)
ret = stream->write(self->stream, buf, sizeof(buf), &err);
self->write->input_checksum = ~0; // CRC32
}
if (ret == MP_STREAM_ERROR) {
return false;
}
// Write starting block.
uzlib_start_block(&self->write->lz77);
return true;
}
#endif
STATIC mp_obj_t deflateio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) {
// args: stream, format=NONE, wbits=0, close=False
mp_arg_check_num(n_args, n_kw, 1, 4, false);
mp_int_t format = n_args > 1 ? mp_obj_get_int(args_in[1]) : DEFLATEIO_FORMAT_AUTO;
mp_int_t wbits = n_args > 2 ? mp_obj_get_int(args_in[2]) : 0;
if (format < DEFLATEIO_FORMAT_MIN || format > DEFLATEIO_FORMAT_MAX) {
mp_raise_ValueError(MP_ERROR_TEXT("format"));
}
if (wbits != 0 && (wbits < 5 || wbits > 15)) {
mp_raise_ValueError(MP_ERROR_TEXT("wbits"));
}
mp_obj_deflateio_t *self = mp_obj_malloc(mp_obj_deflateio_t, type);
self->stream = args_in[0];
self->format = format;
self->window_bits = wbits;
self->read = NULL;
#if MICROPY_PY_DEFLATE_COMPRESS
self->write = NULL;
#endif
self->close = n_args > 3 ? mp_obj_is_true(args_in[3]) : false;
return MP_OBJ_FROM_PTR(self);
}
STATIC mp_uint_t deflateio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
mp_obj_deflateio_t *self = MP_OBJ_TO_PTR(o_in);
if (self->stream == MP_OBJ_NULL || !deflateio_init_read(self)) {
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
}
if (self->read->eof) {
return 0;
}
self->read->decomp.dest = buf;
self->read->decomp.dest_limit = (uint8_t *)buf + size;
int st = uzlib_uncompress_chksum(&self->read->decomp);
if (st == UZLIB_DONE) {
self->read->eof = true;
}
if (st < 0) {
DEBUG_printf("uncompress error=" INT_FMT "\n", st);
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
}
return self->read->decomp.dest - (uint8_t *)buf;
}
#if MICROPY_PY_DEFLATE_COMPRESS
STATIC mp_uint_t deflateio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
mp_obj_deflateio_t *self = MP_OBJ_TO_PTR(self_in);
if (self->stream == MP_OBJ_NULL || !deflateio_init_write(self)) {
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
}
self->write->input_len += size;
if (self->format == DEFLATEIO_FORMAT_ZLIB) {
self->write->input_checksum = uzlib_adler32(buf, size, self->write->input_checksum);
} else if (self->format == DEFLATEIO_FORMAT_GZIP) {
self->write->input_checksum = uzlib_crc32(buf, size, self->write->input_checksum);
}
uzlib_lz77_compress(&self->write->lz77, buf, size);
return size;
}
static inline void put_le32(char *buf, uint32_t value) {
buf[0] = value & 0xff;
buf[1] = value >> 8 & 0xff;
buf[2] = value >> 16 & 0xff;
buf[3] = value >> 24 & 0xff;
}
static inline void put_be32(char *buf, uint32_t value) {
buf[3] = value & 0xff;
buf[2] = value >> 8 & 0xff;
buf[1] = value >> 16 & 0xff;
buf[0] = value >> 24 & 0xff;
}
#endif
STATIC mp_uint_t deflateio_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
if (request == MP_STREAM_CLOSE) {
mp_obj_deflateio_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret = 0;
if (self->stream != MP_OBJ_NULL) {
#if MICROPY_PY_DEFLATE_COMPRESS
if (self->write) {
uzlib_finish_block(&self->write->lz77);
const mp_stream_p_t *stream = mp_get_stream(self->stream);
// Write footer if needed.
if (self->format == DEFLATEIO_FORMAT_ZLIB || self->format == DEFLATEIO_FORMAT_GZIP) {
char footer[8];
size_t footer_len;
if (self->format == DEFLATEIO_FORMAT_ZLIB) {
put_be32(&footer[0], self->write->input_checksum);
footer_len = 4;
} else { // DEFLATEIO_FORMAT_GZIP
put_le32(&footer[0], ~self->write->input_checksum);
put_le32(&footer[4], self->write->input_len);
footer_len = 8;
}
if (stream->write(self->stream, footer, footer_len, errcode) == MP_STREAM_ERROR) {
ret = MP_STREAM_ERROR;
}
}
}
#endif
// Only close the stream if required. e.g. when using io.BytesIO
// it needs to stay open so that getvalue() can be called.
if (self->close) {
mp_stream_close(self->stream);
}
// Either way, free the reference to the stream.
self->stream = MP_OBJ_NULL;
}
return ret;
} else {
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
}
}
STATIC const mp_stream_p_t deflateio_stream_p = {
.read = deflateio_read,
#if MICROPY_PY_DEFLATE_COMPRESS
.write = deflateio_write,
#endif
.ioctl = deflateio_ioctl,
};
#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t deflateio_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
#if MICROPY_PY_DEFLATE_COMPRESS
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj) },
};
STATIC MP_DEFINE_CONST_DICT(deflateio_locals_dict, deflateio_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
deflateio_type,
MP_QSTR_DeflateIO,
MP_TYPE_FLAG_NONE,
make_new, deflateio_make_new,
protocol, &deflateio_stream_p,
locals_dict, &deflateio_locals_dict
);
STATIC const mp_rom_map_elem_t mp_module_deflate_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_deflate) },
{ MP_ROM_QSTR(MP_QSTR_DeflateIO), MP_ROM_PTR(&deflateio_type) },
{ MP_ROM_QSTR(MP_QSTR_AUTO), MP_ROM_INT(DEFLATEIO_FORMAT_AUTO) },
{ MP_ROM_QSTR(MP_QSTR_RAW), MP_ROM_INT(DEFLATEIO_FORMAT_RAW) },
{ MP_ROM_QSTR(MP_QSTR_ZLIB), MP_ROM_INT(DEFLATEIO_FORMAT_ZLIB) },
{ MP_ROM_QSTR(MP_QSTR_GZIP), MP_ROM_INT(DEFLATEIO_FORMAT_GZIP) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_deflate_globals, mp_module_deflate_globals_table);
const mp_obj_module_t mp_module_deflate = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_deflate_globals,
};
MP_REGISTER_MODULE(MP_QSTR_deflate, mp_module_deflate);
#endif // !MICROPY_ENABLE_DYNRUNTIME
// Source files #include'd here to make sure they're compiled in
// only if the module is enabled.
#include "lib/uzlib/tinflate.c"
#include "lib/uzlib/header.c"
#include "lib/uzlib/adler32.c"
#include "lib/uzlib/crc32.c"
#if MICROPY_PY_DEFLATE_COMPRESS
#include "lib/uzlib/lz77.c"
#endif
#endif // MICROPY_PY_DEFLATE

View File

@ -29,13 +29,13 @@
#include "py/runtime.h" #include "py/runtime.h"
#if MICROPY_PY_UHASHLIB #if MICROPY_PY_HASHLIB
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#include "mbedtls/version.h" #include "mbedtls/version.h"
#endif #endif
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_HASHLIB_SHA256
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
@ -45,7 +45,7 @@
#endif #endif
#if MICROPY_PY_UHASHLIB_SHA1 || MICROPY_PY_UHASHLIB_MD5 #if MICROPY_PY_HASHLIB_SHA1 || MICROPY_PY_HASHLIB_MD5
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
#include "lib/axtls/crypto/crypto.h" #include "lib/axtls/crypto/crypto.h"
@ -64,47 +64,47 @@ typedef struct _mp_obj_hash_t {
uintptr_t state[0]; // must be aligned to a machine word uintptr_t state[0]; // must be aligned to a machine word
} mp_obj_hash_t; } mp_obj_hash_t;
static void uhashlib_ensure_not_final(mp_obj_hash_t *self) { static void hashlib_ensure_not_final(mp_obj_hash_t *self) {
if (self->final) { if (self->final) {
mp_raise_ValueError(MP_ERROR_TEXT("hash is final")); mp_raise_ValueError(MP_ERROR_TEXT("hash is final"));
} }
} }
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_HASHLIB_SHA256
STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); STATIC mp_obj_t hashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#if MBEDTLS_VERSION_NUMBER < 0x02070000 #if MBEDTLS_VERSION_NUMBER < 0x02070000 || MBEDTLS_VERSION_NUMBER >= 0x03000000
#define mbedtls_sha256_starts_ret mbedtls_sha256_starts #define mbedtls_sha256_starts_ret mbedtls_sha256_starts
#define mbedtls_sha256_update_ret mbedtls_sha256_update #define mbedtls_sha256_update_ret mbedtls_sha256_update
#define mbedtls_sha256_finish_ret mbedtls_sha256_finish #define mbedtls_sha256_finish_ret mbedtls_sha256_finish
#endif #endif
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type);
o->final = false; o->final = false;
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len); mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, 32); vstr_init_len(&vstr, 32);
@ -124,30 +124,30 @@ static void check_not_unicode(const mp_obj_t arg) {
#include "lib/crypto-algorithms/sha256.c" #include "lib/crypto-algorithms/sha256.c"
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type);
o->final = false; o->final = false;
sha256_init((CRYAL_SHA256_CTX *)o->state); sha256_init((CRYAL_SHA256_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
check_not_unicode(arg); check_not_unicode(arg);
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len); sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, SHA256_BLOCK_SIZE); vstr_init_len(&vstr, SHA256_BLOCK_SIZE);
@ -156,52 +156,52 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
} }
#endif #endif
STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_sha256_update_obj, uhashlib_sha256_update); STATIC MP_DEFINE_CONST_FUN_OBJ_2(hashlib_sha256_update_obj, hashlib_sha256_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_sha256_digest_obj, uhashlib_sha256_digest); STATIC MP_DEFINE_CONST_FUN_OBJ_1(hashlib_sha256_digest_obj, hashlib_sha256_digest);
STATIC const mp_rom_map_elem_t uhashlib_sha256_locals_dict_table[] = { STATIC const mp_rom_map_elem_t hashlib_sha256_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_sha256_update_obj) }, { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&hashlib_sha256_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_sha256_digest_obj) }, { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&hashlib_sha256_digest_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(uhashlib_sha256_locals_dict, uhashlib_sha256_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(hashlib_sha256_locals_dict, hashlib_sha256_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE( STATIC MP_DEFINE_CONST_OBJ_TYPE(
uhashlib_sha256_type, hashlib_sha256_type,
MP_QSTR_sha256, MP_QSTR_sha256,
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
make_new, uhashlib_sha256_make_new, make_new, hashlib_sha256_make_new,
locals_dict, &uhashlib_sha256_locals_dict locals_dict, &hashlib_sha256_locals_dict
); );
#endif #endif
#if MICROPY_PY_UHASHLIB_SHA1 #if MICROPY_PY_HASHLIB_SHA1
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); STATIC mp_obj_t hashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type);
o->final = false; o->final = false;
SHA1_Init((SHA1_CTX *)o->state); SHA1_Init((SHA1_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len); SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, SHA1_SIZE); vstr_init_len(&vstr, SHA1_SIZE);
@ -212,36 +212,36 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#if MBEDTLS_VERSION_NUMBER < 0x02070000 #if MBEDTLS_VERSION_NUMBER < 0x02070000 || MBEDTLS_VERSION_NUMBER >= 0x03000000
#define mbedtls_sha1_starts_ret mbedtls_sha1_starts #define mbedtls_sha1_starts_ret mbedtls_sha1_starts
#define mbedtls_sha1_update_ret mbedtls_sha1_update #define mbedtls_sha1_update_ret mbedtls_sha1_update
#define mbedtls_sha1_finish_ret mbedtls_sha1_finish #define mbedtls_sha1_finish_ret mbedtls_sha1_finish
#endif #endif
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type);
o->final = false; o->final = false;
mbedtls_sha1_init((mbedtls_sha1_context *)o->state); mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len); mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, 20); vstr_init_len(&vstr, 20);
@ -251,51 +251,51 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
} }
#endif #endif
STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_sha1_update_obj, uhashlib_sha1_update); STATIC MP_DEFINE_CONST_FUN_OBJ_2(hashlib_sha1_update_obj, hashlib_sha1_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_sha1_digest_obj, uhashlib_sha1_digest); STATIC MP_DEFINE_CONST_FUN_OBJ_1(hashlib_sha1_digest_obj, hashlib_sha1_digest);
STATIC const mp_rom_map_elem_t uhashlib_sha1_locals_dict_table[] = { STATIC const mp_rom_map_elem_t hashlib_sha1_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_sha1_update_obj) }, { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&hashlib_sha1_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_sha1_digest_obj) }, { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&hashlib_sha1_digest_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(uhashlib_sha1_locals_dict, uhashlib_sha1_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(hashlib_sha1_locals_dict, hashlib_sha1_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE( STATIC MP_DEFINE_CONST_OBJ_TYPE(
uhashlib_sha1_type, hashlib_sha1_type,
MP_QSTR_sha1, MP_QSTR_sha1,
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
make_new, uhashlib_sha1_make_new, make_new, hashlib_sha1_make_new,
locals_dict, &uhashlib_sha1_locals_dict locals_dict, &hashlib_sha1_locals_dict
); );
#endif #endif
#if MICROPY_PY_UHASHLIB_MD5 #if MICROPY_PY_HASHLIB_MD5
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg); STATIC mp_obj_t hashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type);
o->final = false; o->final = false;
MD5_Init((MD5_CTX *)o->state); MD5_Init((MD5_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len); MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, MD5_SIZE); vstr_init_len(&vstr, MD5_SIZE);
@ -312,30 +312,30 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
#define mbedtls_md5_finish_ret mbedtls_md5_finish #define mbedtls_md5_finish_ret mbedtls_md5_finish
#endif #endif
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t hashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type);
o->final = false; o->final = false;
mbedtls_md5_init((mbedtls_md5_context *)o->state); mbedtls_md5_init((mbedtls_md5_context *)o->state);
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); hashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t hashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len); mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { STATIC mp_obj_t hashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); hashlib_ensure_not_final(self);
self->final = true; self->final = true;
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, 16); vstr_init_len(&vstr, 16);
@ -345,44 +345,44 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
} }
#endif // MICROPY_SSL_MBEDTLS #endif // MICROPY_SSL_MBEDTLS
STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_md5_update_obj, uhashlib_md5_update); STATIC MP_DEFINE_CONST_FUN_OBJ_2(hashlib_md5_update_obj, hashlib_md5_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_md5_digest_obj, uhashlib_md5_digest); STATIC MP_DEFINE_CONST_FUN_OBJ_1(hashlib_md5_digest_obj, hashlib_md5_digest);
STATIC const mp_rom_map_elem_t uhashlib_md5_locals_dict_table[] = { STATIC const mp_rom_map_elem_t hashlib_md5_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_md5_update_obj) }, { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&hashlib_md5_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_md5_digest_obj) }, { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&hashlib_md5_digest_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(uhashlib_md5_locals_dict, uhashlib_md5_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(hashlib_md5_locals_dict, hashlib_md5_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE( STATIC MP_DEFINE_CONST_OBJ_TYPE(
uhashlib_md5_type, hashlib_md5_type,
MP_QSTR_md5, MP_QSTR_md5,
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
make_new, uhashlib_md5_make_new, make_new, hashlib_md5_make_new,
locals_dict, &uhashlib_md5_locals_dict locals_dict, &hashlib_md5_locals_dict
); );
#endif // MICROPY_PY_UHASHLIB_MD5 #endif // MICROPY_PY_HASHLIB_MD5
STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_hashlib_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) },
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_HASHLIB_SHA256
{ MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&uhashlib_sha256_type) }, { MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&hashlib_sha256_type) },
#endif #endif
#if MICROPY_PY_UHASHLIB_SHA1 #if MICROPY_PY_HASHLIB_SHA1
{ MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&uhashlib_sha1_type) }, { MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&hashlib_sha1_type) },
#endif #endif
#if MICROPY_PY_UHASHLIB_MD5 #if MICROPY_PY_HASHLIB_MD5
{ MP_ROM_QSTR(MP_QSTR_md5), MP_ROM_PTR(&uhashlib_md5_type) }, { MP_ROM_QSTR(MP_QSTR_md5), MP_ROM_PTR(&hashlib_md5_type) },
#endif #endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_uhashlib_globals, mp_module_uhashlib_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals_table);
const mp_obj_module_t mp_module_uhashlib = { const mp_obj_module_t mp_module_hashlib = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals, .globals = (mp_obj_dict_t *)&mp_module_hashlib_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_hashlib, mp_module_uhashlib); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_hashlib, mp_module_hashlib);
#endif // MICROPY_PY_UHASHLIB #endif // MICROPY_PY_HASHLIB

View File

@ -27,18 +27,18 @@
#include "py/objlist.h" #include "py/objlist.h"
#include "py/runtime.h" #include "py/runtime.h"
#if MICROPY_PY_UHEAPQ #if MICROPY_PY_HEAPQ
// the algorithm here is modelled on CPython's heapq.py // the algorithm here is modelled on CPython's heapq.py
STATIC mp_obj_list_t *uheapq_get_heap(mp_obj_t heap_in) { STATIC mp_obj_list_t *heapq_get_heap(mp_obj_t heap_in) {
if (!mp_obj_is_type(heap_in, &mp_type_list)) { if (!mp_obj_is_type(heap_in, &mp_type_list)) {
mp_raise_TypeError(MP_ERROR_TEXT("heap must be a list")); mp_raise_TypeError(MP_ERROR_TEXT("heap must be a list"));
} }
return MP_OBJ_TO_PTR(heap_in); return MP_OBJ_TO_PTR(heap_in);
} }
STATIC void uheapq_heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) { STATIC void heapq_heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
mp_obj_t item = heap->items[pos]; mp_obj_t item = heap->items[pos];
while (pos > start_pos) { while (pos > start_pos) {
mp_uint_t parent_pos = (pos - 1) >> 1; mp_uint_t parent_pos = (pos - 1) >> 1;
@ -53,7 +53,7 @@ STATIC void uheapq_heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_ui
heap->items[pos] = item; heap->items[pos] = item;
} }
STATIC void uheapq_heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) { STATIC void heapq_heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
mp_uint_t start_pos = pos; mp_uint_t start_pos = pos;
mp_uint_t end_pos = heap->len; mp_uint_t end_pos = heap->len;
mp_obj_t item = heap->items[pos]; mp_obj_t item = heap->items[pos];
@ -67,19 +67,19 @@ STATIC void uheapq_heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
pos = child_pos; pos = child_pos;
} }
heap->items[pos] = item; heap->items[pos] = item;
uheapq_heap_siftdown(heap, start_pos, pos); heapq_heap_siftdown(heap, start_pos, pos);
} }
STATIC mp_obj_t mod_uheapq_heappush(mp_obj_t heap_in, mp_obj_t item) { STATIC mp_obj_t mod_heapq_heappush(mp_obj_t heap_in, mp_obj_t item) {
mp_obj_list_t *heap = uheapq_get_heap(heap_in); mp_obj_list_t *heap = heapq_get_heap(heap_in);
mp_obj_list_append(heap_in, item); mp_obj_list_append(heap_in, item);
uheapq_heap_siftdown(heap, 0, heap->len - 1); heapq_heap_siftdown(heap, 0, heap->len - 1);
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_heapq_heappush_obj, mod_heapq_heappush);
STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) { STATIC mp_obj_t mod_heapq_heappop(mp_obj_t heap_in) {
mp_obj_list_t *heap = uheapq_get_heap(heap_in); mp_obj_list_t *heap = heapq_get_heap(heap_in);
if (heap->len == 0) { if (heap->len == 0) {
mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap")); mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
} }
@ -88,37 +88,37 @@ STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
heap->items[0] = heap->items[heap->len]; heap->items[0] = heap->items[heap->len];
heap->items[heap->len] = MP_OBJ_NULL; // so we don't retain a pointer heap->items[heap->len] = MP_OBJ_NULL; // so we don't retain a pointer
if (heap->len) { if (heap->len) {
uheapq_heap_siftup(heap, 0); heapq_heap_siftup(heap, 0);
} }
return item; return item;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heappop_obj, mod_uheapq_heappop); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_heapq_heappop_obj, mod_heapq_heappop);
STATIC mp_obj_t mod_uheapq_heapify(mp_obj_t heap_in) { STATIC mp_obj_t mod_heapq_heapify(mp_obj_t heap_in) {
mp_obj_list_t *heap = uheapq_get_heap(heap_in); mp_obj_list_t *heap = heapq_get_heap(heap_in);
for (mp_uint_t i = heap->len / 2; i > 0;) { for (mp_uint_t i = heap->len / 2; i > 0;) {
uheapq_heap_siftup(heap, --i); heapq_heap_siftup(heap, --i);
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heapify_obj, mod_uheapq_heapify); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_heapq_heapify_obj, mod_heapq_heapify);
#if !MICROPY_ENABLE_DYNRUNTIME #if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_uheapq_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_heapq_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uheapq) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_heapq) },
{ MP_ROM_QSTR(MP_QSTR_heappush), MP_ROM_PTR(&mod_uheapq_heappush_obj) }, { MP_ROM_QSTR(MP_QSTR_heappush), MP_ROM_PTR(&mod_heapq_heappush_obj) },
{ MP_ROM_QSTR(MP_QSTR_heappop), MP_ROM_PTR(&mod_uheapq_heappop_obj) }, { MP_ROM_QSTR(MP_QSTR_heappop), MP_ROM_PTR(&mod_heapq_heappop_obj) },
{ MP_ROM_QSTR(MP_QSTR_heapify), MP_ROM_PTR(&mod_uheapq_heapify_obj) }, { MP_ROM_QSTR(MP_QSTR_heapify), MP_ROM_PTR(&mod_heapq_heapify_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_uheapq_globals, mp_module_uheapq_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_heapq_globals, mp_module_heapq_globals_table);
const mp_obj_module_t mp_module_uheapq = { const mp_obj_module_t mp_module_heapq = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals, .globals = (mp_obj_dict_t *)&mp_module_heapq_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_heapq, mp_module_uheapq); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_heapq, mp_module_heapq);
#endif #endif
#endif // MICROPY_PY_UHEAPQ #endif // MICROPY_PY_HEAPQ

View File

@ -34,16 +34,16 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h" #include "py/stream.h"
#if MICROPY_PY_UJSON #if MICROPY_PY_JSON
#if MICROPY_PY_UJSON_SEPARATORS #if MICROPY_PY_JSON_SEPARATORS
enum { enum {
DUMP_MODE_TO_STRING = 1, DUMP_MODE_TO_STRING = 1,
DUMP_MODE_TO_STREAM = 2, DUMP_MODE_TO_STREAM = 2,
}; };
STATIC mp_obj_t mod_ujson_dump_helper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, unsigned int mode) { STATIC mp_obj_t mod_json_dump_helper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, unsigned int mode) {
enum { ARG_separators }; enum { ARG_separators };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_separators, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, { MP_QSTR_separators, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
@ -80,34 +80,35 @@ STATIC mp_obj_t mod_ujson_dump_helper(size_t n_args, const mp_obj_t *pos_args, m
} }
} }
STATIC mp_obj_t mod_ujson_dump(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t mod_json_dump(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return mod_ujson_dump_helper(n_args, pos_args, kw_args, DUMP_MODE_TO_STREAM); return mod_json_dump_helper(n_args, pos_args, kw_args, DUMP_MODE_TO_STREAM);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ujson_dump_obj, 2, mod_ujson_dump); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_json_dump_obj, 2, mod_json_dump);
STATIC mp_obj_t mod_ujson_dumps(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t mod_json_dumps(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return mod_ujson_dump_helper(n_args, pos_args, kw_args, DUMP_MODE_TO_STRING); return mod_json_dump_helper(n_args, pos_args, kw_args, DUMP_MODE_TO_STRING);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ujson_dumps_obj, 1, mod_ujson_dumps); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_json_dumps_obj, 1, mod_json_dumps);
#else #else
STATIC mp_obj_t mod_ujson_dump(mp_obj_t obj, mp_obj_t stream) { STATIC mp_obj_t mod_json_dump(mp_obj_t obj, mp_obj_t stream) {
mp_get_stream_raise(stream, MP_STREAM_OP_WRITE); mp_get_stream_raise(stream, MP_STREAM_OP_WRITE);
mp_print_t print = {MP_OBJ_TO_PTR(stream), mp_stream_write_adaptor}; mp_print_t print = {MP_OBJ_TO_PTR(stream), mp_stream_write_adaptor};
mp_obj_print_helper(&print, obj, PRINT_JSON); mp_obj_print_helper(&print, obj, PRINT_JSON);
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ujson_dump_obj, mod_ujson_dump); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_json_dump_obj, mod_json_dump);
STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { STATIC mp_obj_t mod_json_dumps(mp_obj_t obj) {
vstr_t vstr; vstr_t vstr;
mp_print_t print; mp_print_t print;
vstr_init_print(&vstr, 8, &print); vstr_init_print(&vstr, 8, &print);
mp_obj_print_helper(&print, obj, PRINT_JSON); mp_obj_print_helper(&print, obj, PRINT_JSON);
return mp_obj_new_str_from_utf8_vstr(&vstr); return mp_obj_new_str_from_utf8_vstr(&vstr);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_json_dumps_obj, mod_json_dumps);
#endif #endif
#define JSON_DEBUG(...) (void)0 #define JSON_DEBUG(...) (void)0
@ -127,24 +128,24 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
// strings). It does 1 pass over the input stream. It tries to be fast and // strings). It does 1 pass over the input stream. It tries to be fast and
// small in code size, while not using more RAM than necessary. // small in code size, while not using more RAM than necessary.
typedef struct _ujson_stream_t { typedef struct _json_stream_t {
mp_obj_t stream_obj; mp_obj_t stream_obj;
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
int errcode; int errcode;
// CIRCUITPY // CIRCUITPY-CHANGE
mp_obj_t python_readinto[2 + 1]; mp_obj_t python_readinto[2 + 1];
mp_obj_array_t bytearray_obj; mp_obj_array_t bytearray_obj;
size_t start; size_t start;
size_t end; size_t end;
byte cur; byte cur;
} ujson_stream_t; } json_stream_t;
#define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker #define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker
#define S_END(s) ((s).cur == S_EOF) #define S_END(s) ((s).cur == S_EOF)
#define S_CUR(s) ((s).cur) #define S_CUR(s) ((s).cur)
#define S_NEXT(s) (ujson_stream_next(&(s))) #define S_NEXT(s) (json_stream_next(&(s)))
STATIC byte ujson_stream_next(ujson_stream_t *s) { STATIC byte json_stream_next(json_stream_t *s) {
mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode); mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode);
JSON_DEBUG(" usjon_stream_next err:%2d cur: %c \n", s->errcode, s->cur); JSON_DEBUG(" usjon_stream_next err:%2d cur: %c \n", s->errcode, s->cur);
if (s->errcode != 0) { if (s->errcode != 0) {
@ -156,16 +157,16 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
return s->cur; return s->cur;
} }
// CIRCUITPY // CIRCUITPY-CHANGE
// We read from an object's `readinto` method in chunks larger than the json // We read from an object's `readinto` method in chunks larger than the json
// parser needs to reduce the number of function calls done. // parser needs to reduce the number of function calls done.
#define CIRCUITPY_JSON_READ_CHUNK_SIZE 64 #define CIRCUITPY_JSON_READ_CHUNK_SIZE 64
STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t json_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode) {
(void)size; // Ignore size because we know it's always 1. (void)size; // Ignore size because we know it's always 1.
ujson_stream_t *s = obj; json_stream_t *s = obj;
if (s->start == s->end) { if (s->start == s->end) {
*errcode = 0; *errcode = 0;
@ -186,9 +187,9 @@ STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size,
return 1; return 1;
} }
STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) { STATIC mp_obj_t _mod_json_load(mp_obj_t stream_obj, bool return_first_json) {
const mp_stream_p_t *stream_p = mp_proto_get(MP_QSTR_protocol_stream, stream_obj); const mp_stream_p_t *stream_p = mp_proto_get(MP_QSTR_protocol_stream, stream_obj);
ujson_stream_t s; json_stream_t s;
uint8_t character_buffer[CIRCUITPY_JSON_READ_CHUNK_SIZE]; uint8_t character_buffer[CIRCUITPY_JSON_READ_CHUNK_SIZE];
if (stream_p == NULL) { if (stream_p == NULL) {
s.start = 0; s.start = 0;
@ -201,7 +202,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
s.bytearray_obj.items = character_buffer; s.bytearray_obj.items = character_buffer;
s.python_readinto[2] = MP_OBJ_FROM_PTR(&s.bytearray_obj); s.python_readinto[2] = MP_OBJ_FROM_PTR(&s.bytearray_obj);
s.stream_obj = &s; s.stream_obj = &s;
s.read = ujson_python_readinto; s.read = json_python_readinto;
} else { } else {
stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ); stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
s.stream_obj = stream_obj; s.stream_obj = stream_obj;
@ -400,7 +401,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
} }
} }
success: success:
// CIRCUITPY // CIRCUITPY-CHANGE
// It is legal for a stream to have contents after JSON. // It is legal for a stream to have contents after JSON.
// E.g., A UART is not closed after receiving an object; in load() we will // E.g., A UART is not closed after receiving an object; in load() we will
@ -426,39 +427,35 @@ fail:
mp_raise_ValueError(MP_ERROR_TEXT("syntax error in JSON")); mp_raise_ValueError(MP_ERROR_TEXT("syntax error in JSON"));
} }
STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) { STATIC mp_obj_t mod_json_load(mp_obj_t stream_obj) {
return _mod_ujson_load(stream_obj, true); return _mod_json_load(stream_obj, true);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_json_load_obj, mod_json_load);
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { STATIC mp_obj_t mod_json_loads(mp_obj_t obj) {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
vstr_t vstr = {bufinfo.len, bufinfo.len, (char *)bufinfo.buf, true}; vstr_t vstr = {bufinfo.len, bufinfo.len, (char *)bufinfo.buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL}; mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false); return _mod_json_load(MP_OBJ_FROM_PTR(&sio), false);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_json_loads_obj, mod_json_loads);
STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_json_globals_table[] = {
#if CIRCUITPY
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) },
#else { MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_json_dump_obj) },
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) }, { MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_json_dumps_obj) },
#endif { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_json_load_obj) },
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_ujson_dump_obj) }, { MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_json_loads_obj) },
{ MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) },
{ MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) },
{ MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_ujson_loads_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_ujson_globals, mp_module_ujson_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_json_globals, mp_module_json_globals_table);
const mp_obj_module_t mp_module_ujson = { const mp_obj_module_t mp_module_json = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals, .globals = (mp_obj_dict_t *)&mp_module_json_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_json, mp_module_json);
#endif // MICROPY_PY_UJSON #endif // MICROPY_PY_JSON

View File

@ -27,13 +27,17 @@
#include "py/objstr.h" #include "py/objstr.h"
#include "py/runtime.h" #include "py/runtime.h"
#if MICROPY_PY_UOS #if MICROPY_PY_OS
#include "extmod/misc.h" #include "extmod/misc.h"
#include "extmod/vfs.h" #include "extmod/vfs.h"
#if MICROPY_VFS_FAT #if MICROPY_VFS_FAT
#include "extmod/vfs_fat.h" #include "extmod/vfs_fat.h"
#if MICROPY_PY_OS_SYNC
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
#endif
#endif #endif
#if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2 #if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2
@ -44,12 +48,12 @@
#include "extmod/vfs_posix.h" #include "extmod/vfs_posix.h"
#endif #endif
#if MICROPY_PY_UOS_UNAME #if MICROPY_PY_OS_UNAME
#include "genhdr/mpversion.h" #include "genhdr/mpversion.h"
#endif #endif
#ifdef MICROPY_PY_UOS_INCLUDEFILE #ifdef MICROPY_PY_OS_INCLUDEFILE
#include MICROPY_PY_UOS_INCLUDEFILE #include MICROPY_PY_OS_INCLUDEFILE
#endif #endif
#ifdef MICROPY_BUILD_TYPE #ifdef MICROPY_BUILD_TYPE
@ -58,77 +62,87 @@
#define MICROPY_BUILD_TYPE_PAREN #define MICROPY_BUILD_TYPE_PAREN
#endif #endif
#if MICROPY_PY_UOS_UNAME #if MICROPY_PY_OS_SYNC
// sync()
// Sync all filesystems.
STATIC mp_obj_t mp_os_sync(void) {
#if MICROPY_VFS_FAT
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
// this assumes that vfs->obj is fs_user_mount_t with block device functions
disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL);
}
#endif
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_os_sync_obj, mp_os_sync);
#endif
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC #if MICROPY_PY_OS_UNAME
#if MICROPY_PY_OS_UNAME_RELEASE_DYNAMIC
#define CONST_RELEASE #define CONST_RELEASE
#else #else
#define CONST_RELEASE const #define CONST_RELEASE const
#endif #endif
STATIC const qstr mp_uos_uname_info_fields[] = { STATIC const qstr mp_os_uname_info_fields[] = {
MP_QSTR_sysname, MP_QSTR_sysname,
MP_QSTR_nodename, MP_QSTR_nodename,
MP_QSTR_release, MP_QSTR_release,
MP_QSTR_version, MP_QSTR_version,
MP_QSTR_machine MP_QSTR_machine
}; };
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM); STATIC const MP_DEFINE_STR_OBJ(mp_os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM); STATIC const MP_DEFINE_STR_OBJ(mp_os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
STATIC CONST_RELEASE MP_DEFINE_STR_OBJ(mp_uos_uname_info_release_obj, MICROPY_VERSION_STRING); STATIC CONST_RELEASE MP_DEFINE_STR_OBJ(mp_os_uname_info_release_obj, MICROPY_VERSION_STRING);
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE MICROPY_BUILD_TYPE_PAREN); STATIC const MP_DEFINE_STR_OBJ(mp_os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE MICROPY_BUILD_TYPE_PAREN);
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); STATIC const MP_DEFINE_STR_OBJ(mp_os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
STATIC MP_DEFINE_ATTRTUPLE( STATIC MP_DEFINE_ATTRTUPLE(
mp_uos_uname_info_obj, mp_os_uname_info_obj,
mp_uos_uname_info_fields, mp_os_uname_info_fields,
5, 5,
MP_ROM_PTR(&mp_uos_uname_info_sysname_obj), MP_ROM_PTR(&mp_os_uname_info_sysname_obj),
MP_ROM_PTR(&mp_uos_uname_info_nodename_obj), MP_ROM_PTR(&mp_os_uname_info_nodename_obj),
MP_ROM_PTR(&mp_uos_uname_info_release_obj), MP_ROM_PTR(&mp_os_uname_info_release_obj),
MP_ROM_PTR(&mp_uos_uname_info_version_obj), MP_ROM_PTR(&mp_os_uname_info_version_obj),
MP_ROM_PTR(&mp_uos_uname_info_machine_obj) MP_ROM_PTR(&mp_os_uname_info_machine_obj)
); );
STATIC mp_obj_t mp_uos_uname(void) { STATIC mp_obj_t mp_os_uname(void) {
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC #if MICROPY_PY_OS_UNAME_RELEASE_DYNAMIC
const char *release = mp_uos_uname_release(); const char *release = mp_os_uname_release();
mp_uos_uname_info_release_obj.len = strlen(release); mp_os_uname_info_release_obj.len = strlen(release);
mp_uos_uname_info_release_obj.data = (const byte *)release; mp_os_uname_info_release_obj.data = (const byte *)release;
#endif #endif
return MP_OBJ_FROM_PTR(&mp_uos_uname_info_obj); return MP_OBJ_FROM_PTR(&mp_os_uname_info_obj);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_uos_uname_obj, mp_uos_uname); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_os_uname_obj, mp_os_uname);
#endif #endif
STATIC const mp_rom_map_elem_t os_module_globals_table[] = { STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
#if MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV #if MICROPY_PY_OS_GETENV_PUTENV_UNSETENV
{ MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mp_uos_getenv_obj) }, { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mp_os_getenv_obj) },
#if defined(MICROPY_UNIX_COVERAGE) { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_os_putenv_obj) },
{ MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mp_uos_getenv_int_obj) }, { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_os_unsetenv_obj) },
{ MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mp_uos_getenv_str_obj) },
#endif #endif
#if MICROPY_PY_OS_SEP
{ MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_uos_putenv_obj) },
{ MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_uos_unsetenv_obj) },
#endif
#if MICROPY_PY_UOS_SEP
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
#endif #endif
#if MICROPY_PY_UOS_SYNC #if MICROPY_PY_OS_SYNC
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_uos_sync_obj) }, { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_os_sync_obj) },
#endif #endif
#if MICROPY_PY_UOS_SYSTEM #if MICROPY_PY_OS_SYSTEM
{ MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mp_uos_system_obj) }, { MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mp_os_system_obj) },
#endif #endif
#if MICROPY_PY_UOS_UNAME #if MICROPY_PY_OS_UNAME
{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&mp_uos_uname_obj) }, { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&mp_os_uname_obj) },
#endif #endif
#if MICROPY_PY_UOS_URANDOM #if MICROPY_PY_OS_URANDOM
{ MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_uos_urandom_obj) }, { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_os_urandom_obj) },
#endif #endif
#if MICROPY_VFS #if MICROPY_VFS
@ -147,13 +161,13 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
// The following are MicroPython extensions. // The following are MicroPython extensions.
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) }, { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_os_dupterm_obj) },
#endif #endif
#if MICROPY_PY_UOS_DUPTERM_NOTIFY #if MICROPY_PY_OS_DUPTERM_NOTIFY
{ MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&mp_uos_dupterm_notify_obj) }, { MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&mp_os_dupterm_notify_obj) },
#endif #endif
#if MICROPY_PY_UOS_ERRNO #if MICROPY_PY_OS_ERRNO
{ MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_uos_errno_obj) }, { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_os_errno_obj) },
#endif #endif
#if MICROPY_VFS #if MICROPY_VFS
@ -176,11 +190,11 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
}; };
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
const mp_obj_module_t mp_module_uos = { const mp_obj_module_t mp_module_os = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&os_module_globals, .globals = (mp_obj_dict_t *)&os_module_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_os, mp_module_uos); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_os, mp_module_os);
#endif // MICROPY_PY_UOS #endif // MICROPY_PY_OS

View File

@ -29,10 +29,10 @@
#include "py/objtuple.h" #include "py/objtuple.h"
#include "py/objstr.h" #include "py/objstr.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "extmod/moduplatform.h" #include "extmod/modplatform.h"
#include "genhdr/mpversion.h" #include "genhdr/mpversion.h"
#if MICROPY_PY_UPLATFORM #if MICROPY_PY_PLATFORM
// platform - Access to underlying platform's identifying data // platform - Access to underlying platform's identifying data
@ -62,7 +62,7 @@ STATIC mp_obj_t platform_libc_ver(size_t n_args, const mp_obj_t *pos_args, mp_ma
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(platform_libc_ver_obj, 0, platform_libc_ver); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(platform_libc_ver_obj, 0, platform_libc_ver);
STATIC const mp_rom_map_elem_t modplatform_globals_table[] = { STATIC const mp_rom_map_elem_t modplatform_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uplatform) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_platform) },
{ MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&platform_platform_obj) }, { MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&platform_platform_obj) },
{ MP_ROM_QSTR(MP_QSTR_python_compiler), MP_ROM_PTR(&platform_python_compiler_obj) }, { MP_ROM_QSTR(MP_QSTR_python_compiler), MP_ROM_PTR(&platform_python_compiler_obj) },
{ MP_ROM_QSTR(MP_QSTR_libc_ver), MP_ROM_PTR(&platform_libc_ver_obj) }, { MP_ROM_QSTR(MP_QSTR_libc_ver), MP_ROM_PTR(&platform_libc_ver_obj) },
@ -70,11 +70,11 @@ STATIC const mp_rom_map_elem_t modplatform_globals_table[] = {
STATIC MP_DEFINE_CONST_DICT(modplatform_globals, modplatform_globals_table); STATIC MP_DEFINE_CONST_DICT(modplatform_globals, modplatform_globals_table);
const mp_obj_module_t mp_module_uplatform = { const mp_obj_module_t mp_module_platform = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&modplatform_globals, .globals = (mp_obj_dict_t *)&modplatform_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_platform, mp_module_uplatform); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_platform, mp_module_platform);
#endif // MICROPY_PY_UPLATFORM #endif // MICROPY_PY_PLATFORM

View File

@ -23,14 +23,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef MICROPY_INCLUDED_MODUPLATFORM_H #ifndef MICROPY_INCLUDED_MODPLATFORM_H
#define MICROPY_INCLUDED_MODUPLATFORM_H #define MICROPY_INCLUDED_MODPLATFORM_H
#include "py/misc.h" // For MP_STRINGIFY. #include "py/misc.h" // For MP_STRINGIFY.
#include "py/mpconfig.h" #include "py/mpconfig.h"
// Preprocessor directives identifying the platform. // Preprocessor directives identifying the platform.
// The (u)platform module itself is guarded by MICROPY_PY_UPLATFORM, see the // The platform module itself is guarded by MICROPY_PY_PLATFORM, see the
// .c file, but these are made available because they're generally usable. // .c file, but these are made available because they're generally usable.
// TODO: Add more architectures, compilers and libraries. // TODO: Add more architectures, compilers and libraries.
// See: https://sourceforge.net/p/predef/wiki/Home/ // See: https://sourceforge.net/p/predef/wiki/Home/
@ -43,6 +43,8 @@
#define MICROPY_PLATFORM_ARCH "x86" #define MICROPY_PLATFORM_ARCH "x86"
#elif defined(__xtensa__) #elif defined(__xtensa__)
#define MICROPY_PLATFORM_ARCH "xtensa" #define MICROPY_PLATFORM_ARCH "xtensa"
#elif defined(__riscv)
#define MICROPY_PLATFORM_ARCH "riscv"
#else #else
#define MICROPY_PLATFORM_ARCH "" #define MICROPY_PLATFORM_ARCH ""
#endif #endif
@ -102,4 +104,4 @@
#define MICROPY_PLATFORM_VERSION "" #define MICROPY_PLATFORM_VERSION ""
#endif #endif
#endif // MICROPY_INCLUDED_MODUPLATFORM_H #endif // MICROPY_INCLUDED_MODPLATFORM_H

View File

@ -29,10 +29,10 @@
#include "py/runtime.h" #include "py/runtime.h"
#if MICROPY_PY_URANDOM #if MICROPY_PY_RANDOM
// Work out if the seed will be set on import or not. // Work out if the seed will be set on import or not.
#if MICROPY_MODULE_BUILTIN_INIT && defined(MICROPY_PY_URANDOM_SEED_INIT_FUNC) #if MICROPY_MODULE_BUILTIN_INIT && defined(MICROPY_PY_RANDOM_SEED_INIT_FUNC)
#define SEED_ON_IMPORT (1) #define SEED_ON_IMPORT (1)
#else #else
#define SEED_ON_IMPORT (0) #define SEED_ON_IMPORT (0)
@ -67,7 +67,7 @@ STATIC uint32_t yasmarang(void) {
// End of Yasmarang // End of Yasmarang
#if MICROPY_PY_URANDOM_EXTRA_FUNCS #if MICROPY_PY_RANDOM_EXTRA_FUNCS
// returns an unsigned integer below the given argument // returns an unsigned integer below the given argument
// n must not be zero // n must not be zero
@ -85,7 +85,7 @@ STATIC uint32_t yasmarang_randbelow(uint32_t n) {
#endif #endif
STATIC mp_obj_t mod_urandom_getrandbits(mp_obj_t num_in) { STATIC mp_obj_t mod_random_getrandbits(mp_obj_t num_in) {
int n = mp_obj_get_int(num_in); int n = mp_obj_get_int(num_in);
if (n > 32 || n < 0) { if (n > 32 || n < 0) {
mp_raise_ValueError(MP_ERROR_TEXT("bits must be 32 or less")); mp_raise_ValueError(MP_ERROR_TEXT("bits must be 32 or less"));
@ -98,13 +98,13 @@ STATIC mp_obj_t mod_urandom_getrandbits(mp_obj_t num_in) {
mask >>= (32 - n); mask >>= (32 - n);
return mp_obj_new_int_from_uint(yasmarang() & mask); return mp_obj_new_int_from_uint(yasmarang() & mask);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_getrandbits_obj, mod_urandom_getrandbits); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_random_getrandbits_obj, mod_random_getrandbits);
STATIC mp_obj_t mod_urandom_seed(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_random_seed(size_t n_args, const mp_obj_t *args) {
mp_uint_t seed; mp_uint_t seed;
if (n_args == 0 || args[0] == mp_const_none) { if (n_args == 0 || args[0] == mp_const_none) {
#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC #ifdef MICROPY_PY_RANDOM_SEED_INIT_FUNC
seed = MICROPY_PY_URANDOM_SEED_INIT_FUNC; seed = MICROPY_PY_RANDOM_SEED_INIT_FUNC;
#else #else
mp_raise_ValueError(MP_ERROR_TEXT("no default seed")); mp_raise_ValueError(MP_ERROR_TEXT("no default seed"));
#endif #endif
@ -117,11 +117,11 @@ STATIC mp_obj_t mod_urandom_seed(size_t n_args, const mp_obj_t *args) {
yasmarang_dat = 0; yasmarang_dat = 0;
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_urandom_seed_obj, 0, 1, mod_urandom_seed); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_random_seed_obj, 0, 1, mod_random_seed);
#if MICROPY_PY_URANDOM_EXTRA_FUNCS #if MICROPY_PY_RANDOM_EXTRA_FUNCS
STATIC mp_obj_t mod_urandom_randrange(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_random_randrange(size_t n_args, const mp_obj_t *args) {
mp_int_t start = mp_obj_get_int(args[0]); mp_int_t start = mp_obj_get_int(args[0]);
if (n_args == 1) { if (n_args == 1) {
// range(stop) // range(stop)
@ -161,9 +161,9 @@ STATIC mp_obj_t mod_urandom_randrange(size_t n_args, const mp_obj_t *args) {
error: error:
mp_raise_ValueError(NULL); mp_raise_ValueError(NULL);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_urandom_randrange_obj, 1, 3, mod_urandom_randrange); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_random_randrange_obj, 1, 3, mod_random_randrange);
STATIC mp_obj_t mod_urandom_randint(mp_obj_t a_in, mp_obj_t b_in) { STATIC mp_obj_t mod_random_randint(mp_obj_t a_in, mp_obj_t b_in) {
mp_int_t a = mp_obj_get_int(a_in); mp_int_t a = mp_obj_get_int(a_in);
mp_int_t b = mp_obj_get_int(b_in); mp_int_t b = mp_obj_get_int(b_in);
if (a <= b) { if (a <= b) {
@ -172,9 +172,9 @@ STATIC mp_obj_t mod_urandom_randint(mp_obj_t a_in, mp_obj_t b_in) {
mp_raise_ValueError(NULL); mp_raise_ValueError(NULL);
} }
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_randint_obj, mod_urandom_randint); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_random_randint_obj, mod_random_randint);
STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) { STATIC mp_obj_t mod_random_choice(mp_obj_t seq) {
mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); mp_int_t len = mp_obj_get_int(mp_obj_len(seq));
if (len > 0) { if (len > 0) {
return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL); return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL);
@ -182,7 +182,7 @@ STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) {
mp_raise_type(&mp_type_IndexError); mp_raise_type(&mp_type_IndexError);
} }
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_choice_obj, mod_urandom_choice); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_random_choice_obj, mod_random_choice);
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
@ -199,63 +199,63 @@ STATIC mp_float_t yasmarang_float(void) {
return u.f - 1; return u.f - 1;
} }
STATIC mp_obj_t mod_urandom_random(void) { STATIC mp_obj_t mod_random_random(void) {
return mp_obj_new_float(yasmarang_float()); return mp_obj_new_float(yasmarang_float());
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom_random_obj, mod_urandom_random); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_random_random_obj, mod_random_random);
STATIC mp_obj_t mod_urandom_uniform(mp_obj_t a_in, mp_obj_t b_in) { STATIC mp_obj_t mod_random_uniform(mp_obj_t a_in, mp_obj_t b_in) {
mp_float_t a = mp_obj_get_float(a_in); mp_float_t a = mp_obj_get_float(a_in);
mp_float_t b = mp_obj_get_float(b_in); mp_float_t b = mp_obj_get_float(b_in);
return mp_obj_new_float(a + (b - a) * yasmarang_float()); return mp_obj_new_float(a + (b - a) * yasmarang_float());
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_random_uniform_obj, mod_random_uniform);
#endif #endif
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS #endif // MICROPY_PY_RANDOM_EXTRA_FUNCS
#if SEED_ON_IMPORT #if SEED_ON_IMPORT
STATIC mp_obj_t mod_urandom___init__(void) { STATIC mp_obj_t mod_random___init__(void) {
// This module may be imported by more than one name so need to ensure // This module may be imported by more than one name so need to ensure
// that it's only ever seeded once. // that it's only ever seeded once.
static bool seeded = false; static bool seeded = false;
if (!seeded) { if (!seeded) {
seeded = true; seeded = true;
mod_urandom_seed(0, NULL); mod_random_seed(0, NULL);
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom___init___obj, mod_urandom___init__); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_random___init___obj, mod_random___init__);
#endif #endif
#if !MICROPY_ENABLE_DYNRUNTIME #if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_urandom_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_random_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_urandom) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_random) },
#if SEED_ON_IMPORT #if SEED_ON_IMPORT
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&mod_urandom___init___obj) }, { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&mod_random___init___obj) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_urandom_getrandbits_obj) }, { MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_random_getrandbits_obj) },
{ MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_urandom_seed_obj) }, { MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_random_seed_obj) },
#if MICROPY_PY_URANDOM_EXTRA_FUNCS #if MICROPY_PY_RANDOM_EXTRA_FUNCS
{ MP_ROM_QSTR(MP_QSTR_randrange), MP_ROM_PTR(&mod_urandom_randrange_obj) }, { MP_ROM_QSTR(MP_QSTR_randrange), MP_ROM_PTR(&mod_random_randrange_obj) },
{ MP_ROM_QSTR(MP_QSTR_randint), MP_ROM_PTR(&mod_urandom_randint_obj) }, { MP_ROM_QSTR(MP_QSTR_randint), MP_ROM_PTR(&mod_random_randint_obj) },
{ MP_ROM_QSTR(MP_QSTR_choice), MP_ROM_PTR(&mod_urandom_choice_obj) }, { MP_ROM_QSTR(MP_QSTR_choice), MP_ROM_PTR(&mod_random_choice_obj) },
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
{ MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_urandom_random_obj) }, { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_random_random_obj) },
{ MP_ROM_QSTR(MP_QSTR_uniform), MP_ROM_PTR(&mod_urandom_uniform_obj) }, { MP_ROM_QSTR(MP_QSTR_uniform), MP_ROM_PTR(&mod_random_uniform_obj) },
#endif #endif
#endif #endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_urandom_globals, mp_module_urandom_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_random_globals, mp_module_random_globals_table);
const mp_obj_module_t mp_module_urandom = { const mp_obj_module_t mp_module_random = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals, .globals = (mp_obj_dict_t *)&mp_module_random_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_random, mp_module_urandom); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_random, mp_module_random);
#endif #endif
#endif // MICROPY_PY_URANDOM #endif // MICROPY_PY_RANDOM

View File

@ -37,7 +37,7 @@
#include "py/unicode.h" #include "py/unicode.h"
#endif #endif
#if MICROPY_PY_URE #if MICROPY_PY_RE
#define re1_5_stack_chk() MP_STACK_CHECK() #define re1_5_stack_chk() MP_STACK_CHECK()
@ -85,7 +85,7 @@ STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
} }
MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group); MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group);
#if MICROPY_PY_URE_MATCH_GROUPS #if MICROPY_PY_RE_MATCH_GROUPS
STATIC mp_obj_t match_groups(mp_obj_t self_in) { STATIC mp_obj_t match_groups(mp_obj_t self_in) {
mp_obj_match_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_match_t *self = MP_OBJ_TO_PTR(self_in);
@ -102,7 +102,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(match_groups_obj, match_groups);
#endif #endif
#if MICROPY_PY_URE_MATCH_SPAN_START_END #if MICROPY_PY_RE_MATCH_SPAN_START_END
STATIC void match_span_helper(size_t n_args, const mp_obj_t *args, mp_obj_t span[2]) { STATIC void match_span_helper(size_t n_args, const mp_obj_t *args, mp_obj_t span[2]) {
mp_obj_match_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_match_t *self = MP_OBJ_TO_PTR(args[0]);
@ -167,10 +167,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_end_obj, 1, 2, match_end);
#if !MICROPY_ENABLE_DYNRUNTIME #if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t match_locals_dict_table[] = { STATIC const mp_rom_map_elem_t match_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_group), MP_ROM_PTR(&match_group_obj) }, { MP_ROM_QSTR(MP_QSTR_group), MP_ROM_PTR(&match_group_obj) },
#if MICROPY_PY_URE_MATCH_GROUPS #if MICROPY_PY_RE_MATCH_GROUPS
{ MP_ROM_QSTR(MP_QSTR_groups), MP_ROM_PTR(&match_groups_obj) }, { MP_ROM_QSTR(MP_QSTR_groups), MP_ROM_PTR(&match_groups_obj) },
#endif #endif
#if MICROPY_PY_URE_MATCH_SPAN_START_END #if MICROPY_PY_RE_MATCH_SPAN_START_END
{ MP_ROM_QSTR(MP_QSTR_span), MP_ROM_PTR(&match_span_obj) }, { MP_ROM_QSTR(MP_QSTR_span), MP_ROM_PTR(&match_span_obj) },
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&match_start_obj) }, { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&match_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_end), MP_ROM_PTR(&match_end_obj) }, { MP_ROM_QSTR(MP_QSTR_end), MP_ROM_PTR(&match_end_obj) },
@ -194,7 +194,7 @@ STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
mp_printf(print, "<re %p>", self); mp_printf(print, "<re %p>", self);
} }
STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
mp_obj_re_t *self; mp_obj_re_t *self;
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) { if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
@ -206,7 +206,8 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
size_t len; size_t len;
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len); subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len; subj.end = subj.begin + len;
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME) // CIRCUITPY-CHANGE
#if MICROPY_PY_RE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
if (n_args > 2) { if (n_args > 2) {
const mp_obj_type_t *self_type = mp_obj_get_type(args[1]); const mp_obj_type_t *self_type = mp_obj_get_type(args[1]);
@ -253,12 +254,12 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
} }
STATIC mp_obj_t re_match(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t re_match(size_t n_args, const mp_obj_t *args) {
return ure_exec(true, n_args, args); return re_exec(true, n_args, args);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match);
STATIC mp_obj_t re_search(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t re_search(size_t n_args, const mp_obj_t *args) {
return ure_exec(false, n_args, args); return re_exec(false, n_args, args);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search);
@ -307,7 +308,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split);
#if MICROPY_PY_URE_SUB #if MICROPY_PY_RE_SUB
STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
mp_obj_re_t *self; mp_obj_re_t *self;
@ -435,7 +436,7 @@ STATIC const mp_rom_map_elem_t re_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) }, { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) }, { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) },
{ MP_ROM_QSTR(MP_QSTR_split), MP_ROM_PTR(&re_split_obj) }, { MP_ROM_QSTR(MP_QSTR_split), MP_ROM_PTR(&re_split_obj) },
#if MICROPY_PY_URE_SUB #if MICROPY_PY_RE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) }, { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) },
#endif #endif
}; };
@ -444,11 +445,7 @@ STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE( STATIC MP_DEFINE_CONST_OBJ_TYPE(
re_type, re_type,
#if CIRCUITPY
MP_QSTR_re, MP_QSTR_re,
#else
MP_QSTR_ure,
#endif
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
print, re_print, print, re_print,
locals_dict, &re_locals_dict locals_dict, &re_locals_dict
@ -463,7 +460,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
goto error; goto error;
} }
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, (mp_obj_type_t *)&re_type); mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, (mp_obj_type_t *)&re_type);
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_RE_DEBUG
int flags = 0; int flags = 0;
if (n_args > 1) { if (n_args > 1) {
flags = mp_obj_get_int(args[1]); flags = mp_obj_get_int(args[1]);
@ -474,7 +471,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
error: error:
mp_raise_ValueError(MP_ERROR_TEXT("Error in regex")); mp_raise_ValueError(MP_ERROR_TEXT("Error in regex"));
} }
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_RE_DEBUG
if (flags & FLAG_DEBUG) { if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re); re1_5_dumpcode(&o->re);
} }
@ -485,30 +482,26 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);
#if !MICROPY_ENABLE_DYNRUNTIME #if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
#if CIRCUITPY
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) },
#else
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) },
#endif
{ MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) }, { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) }, { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) }, { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) },
#if MICROPY_PY_URE_SUB #if MICROPY_PY_RE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) }, { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) },
#endif #endif
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_RE_DEBUG
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) }, { MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
#endif #endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table);
const mp_obj_module_t mp_module_ure = { const mp_obj_module_t mp_module_re = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_re_globals, .globals = (mp_obj_dict_t *)&mp_module_re_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_re, mp_module_re);
#endif #endif
// Source files #include'd here to make sure they're compiled in // Source files #include'd here to make sure they're compiled in
@ -520,11 +513,11 @@ MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure);
#include "lib/re1.5/recursiveloop.c" #include "lib/re1.5/recursiveloop.c"
#include "lib/re1.5/charclass.c" #include "lib/re1.5/charclass.c"
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_RE_DEBUG
// Make sure the output print statements go to the same output as other Python output. // Make sure the output print statements go to the same output as other Python output.
#define printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) #define printf(...) mp_printf(&mp_plat_print, __VA_ARGS__)
#include "lib/re1.5/dumpcode.c" #include "lib/re1.5/dumpcode.c"
#undef printf #undef printf
#endif #endif
#endif // MICROPY_PY_URE #endif // MICROPY_PY_RE

647
extmod/modselect.c Normal file
View File

@ -0,0 +1,647 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014-2023 Damien P. George
* Copyright (c) 2015-2017 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h"
#include "py/runtime.h"
#include "py/obj.h"
#include "py/objlist.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "shared/runtime/interrupt_char.h"
#if MICROPY_PY_SELECT
#if MICROPY_PY_SELECT_SELECT && MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
#error "select.select is not supported with MICROPY_PY_SELECT_POSIX_OPTIMISATIONS"
#endif
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
#include <poll.h>
#if !((MP_STREAM_POLL_RD) == (POLLIN) && \
(MP_STREAM_POLL_WR) == (POLLOUT) && \
(MP_STREAM_POLL_ERR) == (POLLERR) && \
(MP_STREAM_POLL_HUP) == (POLLHUP) && \
(MP_STREAM_POLL_NVAL) == (POLLNVAL))
#error "With MICROPY_PY_SELECT_POSIX_OPTIMISATIONS enabled, POLL constants must match"
#endif
// When non-file-descriptor objects are on the list to be polled (the polling of
// which involves repeatedly calling ioctl(MP_STREAM_POLL)), this variable sets
// the period between polling these objects.
#define MICROPY_PY_SELECT_IOCTL_CALL_PERIOD_MS (1)
#endif
// Flags for ipoll()
#define FLAG_ONESHOT (1)
// A single pollable object.
typedef struct _poll_obj_t {
mp_obj_t obj;
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
// If the pollable object has an associated file descriptor, then pollfd points to an entry
// in poll_set_t::pollfds, and the events/revents fields for this object are stored in the
// pollfd entry (and the nonfd_* members are unused).
// Otherwise the object is a non-file-descriptor object and pollfd==NULL, and the events/
// revents fields are stored in the nonfd_* members (which are named as such so that code
// doesn't accidentally mix the use of these members when this optimisation is used).
struct pollfd *pollfd;
uint16_t nonfd_events;
uint16_t nonfd_revents;
#else
mp_uint_t events;
mp_uint_t revents;
#endif
} poll_obj_t;
// A set of pollable objects.
typedef struct _poll_set_t {
// Map containing a dict with key=object to poll, value=its corresponding poll_obj_t.
mp_map_t map;
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
// Array of pollfd entries for objects that have a file descriptor.
unsigned short alloc; // memory allocated for pollfds
unsigned short max_used; // maximum number of used entries in pollfds
unsigned short used; // actual number of used entries in pollfds
struct pollfd *pollfds;
#endif
} poll_set_t;
STATIC void poll_set_init(poll_set_t *poll_set, size_t n) {
mp_map_init(&poll_set->map, n);
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
poll_set->alloc = 0;
poll_set->max_used = 0;
poll_set->used = 0;
poll_set->pollfds = NULL;
#endif
}
#if MICROPY_PY_SELECT_SELECT
STATIC void poll_set_deinit(poll_set_t *poll_set) {
mp_map_deinit(&poll_set->map);
}
#endif
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
STATIC mp_uint_t poll_obj_get_events(poll_obj_t *poll_obj) {
assert(poll_obj->pollfd == NULL);
return poll_obj->nonfd_events;
}
STATIC void poll_obj_set_events(poll_obj_t *poll_obj, mp_uint_t events) {
if (poll_obj->pollfd != NULL) {
poll_obj->pollfd->events = events;
} else {
poll_obj->nonfd_events = events;
}
}
STATIC mp_uint_t poll_obj_get_revents(poll_obj_t *poll_obj) {
if (poll_obj->pollfd != NULL) {
return poll_obj->pollfd->revents;
} else {
return poll_obj->nonfd_revents;
}
}
STATIC void poll_obj_set_revents(poll_obj_t *poll_obj, mp_uint_t revents) {
if (poll_obj->pollfd != NULL) {
poll_obj->pollfd->revents = revents;
} else {
poll_obj->nonfd_revents = revents;
}
}
STATIC struct pollfd *poll_set_add_fd(poll_set_t *poll_set, int fd) {
struct pollfd *free_slot = NULL;
if (poll_set->used == poll_set->max_used) {
// No free slots below max_used, so expand max_used (and possibly allocate).
if (poll_set->max_used >= poll_set->alloc) {
poll_set->pollfds = m_renew(struct pollfd, poll_set->pollfds, poll_set->alloc, poll_set->alloc + 4);
poll_set->alloc += 4;
}
free_slot = &poll_set->pollfds[poll_set->max_used++];
} else {
// There should be a free slot below max_used.
for (unsigned int i = 0; i < poll_set->max_used; ++i) {
struct pollfd *slot = &poll_set->pollfds[i];
if (slot->fd == -1) {
free_slot = slot;
break;
}
}
assert(free_slot != NULL);
}
free_slot->fd = fd;
++poll_set->used;
return free_slot;
}
static inline bool poll_set_all_are_fds(poll_set_t *poll_set) {
return poll_set->map.used == poll_set->used;
}
#else
static inline mp_uint_t poll_obj_get_events(poll_obj_t *poll_obj) {
return poll_obj->events;
}
static inline void poll_obj_set_events(poll_obj_t *poll_obj, mp_uint_t events) {
poll_obj->events = events;
}
static inline mp_uint_t poll_obj_get_revents(poll_obj_t *poll_obj) {
return poll_obj->revents;
}
static inline void poll_obj_set_revents(poll_obj_t *poll_obj, mp_uint_t revents) {
poll_obj->revents = revents;
}
#endif
STATIC void poll_set_add_obj(poll_set_t *poll_set, const mp_obj_t *obj, mp_uint_t obj_len, mp_uint_t events, bool or_events) {
for (mp_uint_t i = 0; i < obj_len; i++) {
mp_map_elem_t *elem = mp_map_lookup(&poll_set->map, mp_obj_id(obj[i]), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
if (elem->value == MP_OBJ_NULL) {
// object not found; get its ioctl and add it to the poll list
// If an exception is raised below when adding the new object then the map entry for that
// object remains unpopulated, and methods like poll() may crash. This case is not handled.
poll_obj_t *poll_obj = m_new_obj(poll_obj_t);
poll_obj->obj = obj[i];
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
int fd = -1;
if (mp_obj_is_int(obj[i])) {
// A file descriptor integer passed in as the object, so use it directly.
fd = mp_obj_get_int(obj[i]);
if (fd < 0) {
mp_raise_ValueError(NULL);
}
poll_obj->ioctl = NULL;
} else {
// An object passed in. Check if it has a file descriptor.
const mp_stream_p_t *stream_p = mp_get_stream_raise(obj[i], MP_STREAM_OP_IOCTL);
poll_obj->ioctl = stream_p->ioctl;
int err;
mp_uint_t res = stream_p->ioctl(obj[i], MP_STREAM_GET_FILENO, 0, &err);
if (res != MP_STREAM_ERROR) {
fd = res;
}
}
if (fd >= 0) {
// Object has a file descriptor so add it to pollfds.
poll_obj->pollfd = poll_set_add_fd(poll_set, fd);
} else {
// Object doesn't have a file descriptor.
poll_obj->pollfd = NULL;
}
#else
const mp_stream_p_t *stream_p = mp_get_stream_raise(obj[i], MP_STREAM_OP_IOCTL);
poll_obj->ioctl = stream_p->ioctl;
#endif
poll_obj_set_events(poll_obj, events);
poll_obj_set_revents(poll_obj, 0);
elem->value = MP_OBJ_FROM_PTR(poll_obj);
} else {
// object exists; update its events
poll_obj_t *poll_obj = (poll_obj_t *)MP_OBJ_TO_PTR(elem->value);
#if MICROPY_PY_SELECT_SELECT
if (or_events) {
events |= poll_obj_get_events(poll_obj);
}
#else
(void)or_events;
#endif
poll_obj_set_events(poll_obj, events);
}
}
}
// For each object in the poll set, poll it once.
STATIC mp_uint_t poll_set_poll_once(poll_set_t *poll_set, size_t *rwx_num) {
mp_uint_t n_ready = 0;
for (mp_uint_t i = 0; i < poll_set->map.alloc; ++i) {
if (!mp_map_slot_is_filled(&poll_set->map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_set->map.table[i].value);
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
if (poll_obj->pollfd != NULL) {
// Object has file descriptor so will be polled separately by poll().
continue;
}
#endif
int errcode;
mp_int_t ret = poll_obj->ioctl(poll_obj->obj, MP_STREAM_POLL, poll_obj_get_events(poll_obj), &errcode);
poll_obj_set_revents(poll_obj, ret);
if (ret == -1) {
// error doing ioctl
mp_raise_OSError(errcode);
}
if (ret != 0) {
// object is ready
n_ready += 1;
#if MICROPY_PY_SELECT_SELECT
if (rwx_num != NULL) {
if (ret & MP_STREAM_POLL_RD) {
rwx_num[0] += 1;
}
if (ret & MP_STREAM_POLL_WR) {
rwx_num[1] += 1;
}
if ((ret & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) {
rwx_num[2] += 1;
}
}
#else
(void)rwx_num;
#endif
}
}
return n_ready;
}
STATIC mp_uint_t poll_set_poll_until_ready_or_timeout(poll_set_t *poll_set, size_t *rwx_num, mp_uint_t timeout) {
mp_uint_t start_ticks = mp_hal_ticks_ms();
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
for (;;) {
MP_THREAD_GIL_EXIT();
// Compute the timeout.
int t = MICROPY_PY_SELECT_IOCTL_CALL_PERIOD_MS;
if (poll_set_all_are_fds(poll_set)) {
// All our pollables are file descriptors, so we can use a blocking
// poll and let it (the underlying system) handle the timeout.
if (timeout == (mp_uint_t)-1) {
t = -1;
} else {
mp_uint_t delta = mp_hal_ticks_ms() - start_ticks;
if (delta >= timeout) {
t = 0;
} else {
t = timeout - delta;
}
}
}
// Call system poll for those objects that have a file descriptor.
int n_ready = poll(poll_set->pollfds, poll_set->max_used, t);
MP_THREAD_GIL_ENTER();
// The call to poll() may have been interrupted, but per PEP 475 we must retry if the
// signal is EINTR (this implements a special case of calling MP_HAL_RETRY_SYSCALL()).
if (n_ready == -1) {
int err = errno;
if (err != EINTR) {
mp_raise_OSError(err);
}
n_ready = 0;
}
// Explicitly poll any objects that do not have a file descriptor.
if (!poll_set_all_are_fds(poll_set)) {
n_ready += poll_set_poll_once(poll_set, rwx_num);
}
// Return if an object is ready, or if the timeout expired.
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_ticks >= timeout)) {
return n_ready;
}
// This would be MICROPY_EVENT_POLL_HOOK but the call to poll() above already includes a delay.
mp_handle_pending(true);
}
#else
for (;;) {
// poll the objects
mp_uint_t n_ready = poll_set_poll_once(poll_set, rwx_num);
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_ticks >= timeout)) {
return n_ready;
}
// CIRCUITPY-CHANGE
RUN_BACKGROUND_TASKS;
if (mp_hal_is_interrupted()) {
return 0;
}
#ifdef MICROPY_EVENT_POLL_HOOK
MICROPY_EVENT_POLL_HOOK;
#endif
}
#endif
}
#if MICROPY_PY_SELECT_SELECT
// select(rlist, wlist, xlist[, timeout])
STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
// get array data from tuple/list arguments
size_t rwx_len[3];
mp_obj_t *r_array, *w_array, *x_array;
mp_obj_get_array(args[0], &rwx_len[0], &r_array);
mp_obj_get_array(args[1], &rwx_len[1], &w_array);
mp_obj_get_array(args[2], &rwx_len[2], &x_array);
// get timeout
mp_uint_t timeout = -1;
if (n_args == 4) {
if (args[3] != mp_const_none) {
#if MICROPY_PY_BUILTINS_FLOAT
float timeout_f = mp_obj_get_float_to_f(args[3]);
if (timeout_f >= 0) {
timeout = (mp_uint_t)(timeout_f * 1000);
}
#else
timeout = mp_obj_get_int(args[3]) * 1000;
#endif
}
}
// merge separate lists and get the ioctl function for each object
poll_set_t poll_set;
poll_set_init(&poll_set, rwx_len[0] + rwx_len[1] + rwx_len[2]);
poll_set_add_obj(&poll_set, r_array, rwx_len[0], MP_STREAM_POLL_RD, true);
poll_set_add_obj(&poll_set, w_array, rwx_len[1], MP_STREAM_POLL_WR, true);
poll_set_add_obj(&poll_set, x_array, rwx_len[2], MP_STREAM_POLL_ERR | MP_STREAM_POLL_HUP, true);
// poll all objects
rwx_len[0] = rwx_len[1] = rwx_len[2] = 0;
poll_set_poll_until_ready_or_timeout(&poll_set, rwx_len, timeout);
// one or more objects are ready, or we had a timeout
mp_obj_t list_array[3];
list_array[0] = mp_obj_new_list(rwx_len[0], NULL);
list_array[1] = mp_obj_new_list(rwx_len[1], NULL);
list_array[2] = mp_obj_new_list(rwx_len[2], NULL);
rwx_len[0] = rwx_len[1] = rwx_len[2] = 0;
for (mp_uint_t i = 0; i < poll_set.map.alloc; ++i) {
if (!mp_map_slot_is_filled(&poll_set.map, i)) {
continue;
}
// CIRCUITPY-CHANGE
RUN_BACKGROUND_TASKS;
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_set.map.table[i].value);
if (poll_obj->revents & MP_STREAM_POLL_RD) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[0]))->items[rwx_len[0]++] = poll_obj->obj;
}
if (poll_obj->revents & MP_STREAM_POLL_WR) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[1]))->items[rwx_len[1]++] = poll_obj->obj;
}
if ((poll_obj->revents & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[2]))->items[rwx_len[2]++] = poll_obj->obj;
}
}
poll_set_deinit(&poll_set);
return mp_obj_new_tuple(3, list_array);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_select_obj, 3, 4, select_select);
#endif // MICROPY_PY_SELECT_SELECT
typedef struct _mp_obj_poll_t {
mp_obj_base_t base;
poll_set_t poll_set;
short iter_cnt;
short iter_idx;
int flags;
// callee-owned tuple
mp_obj_t ret_tuple;
} mp_obj_poll_t;
// register(obj[, eventmask])
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t events;
if (n_args == 3) {
events = mp_obj_get_int(args[2]);
} else {
events = MP_STREAM_POLL_RD | MP_STREAM_POLL_WR;
}
poll_set_add_obj(&self->poll_set, &args[1], 1, events, false);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register);
// unregister(obj)
STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->poll_set.map, mp_obj_id(obj_in), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
if (elem != NULL) {
poll_obj_t *poll_obj = (poll_obj_t *)MP_OBJ_TO_PTR(elem->value);
if (poll_obj->pollfd != NULL) {
poll_obj->pollfd->fd = -1;
--self->poll_set.used;
}
elem->value = MP_OBJ_NULL;
}
#else
(void)elem;
#endif
// TODO raise KeyError if obj didn't exist in map
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister);
// modify(obj, eventmask)
STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->poll_set.map, mp_obj_id(obj_in), MP_MAP_LOOKUP);
if (elem == NULL) {
mp_raise_OSError(MP_ENOENT);
}
poll_obj_set_events((poll_obj_t *)MP_OBJ_TO_PTR(elem->value), mp_obj_get_int(eventmask_in));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify);
STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
// work out timeout (its given already in ms)
mp_uint_t timeout = -1;
int flags = 0;
if (n_args >= 2) {
if (args[1] != mp_const_none) {
mp_int_t timeout_i = mp_obj_get_int(args[1]);
if (timeout_i >= 0) {
timeout = timeout_i;
}
}
if (n_args >= 3) {
flags = mp_obj_get_int(args[2]);
}
}
self->flags = flags;
return poll_set_poll_until_ready_or_timeout(&self->poll_set, NULL, timeout);
}
STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t n_ready = poll_poll_internal(n_args, args);
// one or more objects are ready, or we had a timeout
mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL));
n_ready = 0;
for (mp_uint_t i = 0; i < self->poll_set.map.alloc; ++i) {
if (!mp_map_slot_is_filled(&self->poll_set.map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_set.map.table[i].value);
if (poll_obj_get_revents(poll_obj) != 0) {
mp_obj_t tuple[2] = {poll_obj->obj, MP_OBJ_NEW_SMALL_INT(poll_obj_get_revents(poll_obj))};
ret_list->items[n_ready++] = mp_obj_new_tuple(2, tuple);
}
}
return MP_OBJ_FROM_PTR(ret_list);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 2, poll_poll);
STATIC mp_obj_t poll_ipoll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
if (self->ret_tuple == MP_OBJ_NULL) {
self->ret_tuple = mp_obj_new_tuple(2, NULL);
}
int n_ready = poll_poll_internal(n_args, args);
self->iter_cnt = n_ready;
self->iter_idx = 0;
return args[0];
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_ipoll_obj, 1, 3, poll_ipoll);
STATIC mp_obj_t poll_iternext(mp_obj_t self_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
if (self->iter_cnt == 0) {
return MP_OBJ_STOP_ITERATION;
}
self->iter_cnt--;
for (mp_uint_t i = self->iter_idx; i < self->poll_set.map.alloc; ++i) {
self->iter_idx++;
if (!mp_map_slot_is_filled(&self->poll_set.map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_set.map.table[i].value);
if (poll_obj_get_revents(poll_obj) != 0) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple);
t->items[0] = poll_obj->obj;
t->items[1] = MP_OBJ_NEW_SMALL_INT(poll_obj_get_revents(poll_obj));
if (self->flags & FLAG_ONESHOT) {
// Don't poll next time, until new event mask will be set explicitly
poll_obj_set_events(poll_obj, 0);
}
return MP_OBJ_FROM_PTR(t);
}
}
assert(!"inconsistent number of poll active entries");
self->iter_cnt = 0;
return MP_OBJ_STOP_ITERATION;
}
STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) },
{ MP_ROM_QSTR(MP_QSTR_unregister), MP_ROM_PTR(&poll_unregister_obj) },
{ MP_ROM_QSTR(MP_QSTR_modify), MP_ROM_PTR(&poll_modify_obj) },
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&poll_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipoll), MP_ROM_PTR(&poll_ipoll_obj) },
};
STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_poll,
MP_QSTR_poll,
MP_TYPE_FLAG_ITER_IS_ITERNEXT,
iter, poll_iternext,
locals_dict, &poll_locals_dict
);
// poll()
STATIC mp_obj_t select_poll(void) {
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
poll_set_init(&poll->poll_set, 0);
poll->iter_cnt = 0;
poll->ret_tuple = MP_OBJ_NULL;
return MP_OBJ_FROM_PTR(poll);
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_select_poll_obj, select_poll);
STATIC const mp_rom_map_elem_t mp_module_select_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_select) },
#if MICROPY_PY_SELECT_SELECT
{ MP_ROM_QSTR(MP_QSTR_select), MP_ROM_PTR(&mp_select_select_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mp_select_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_POLLIN), MP_ROM_INT(MP_STREAM_POLL_RD) },
{ MP_ROM_QSTR(MP_QSTR_POLLOUT), MP_ROM_INT(MP_STREAM_POLL_WR) },
{ MP_ROM_QSTR(MP_QSTR_POLLERR), MP_ROM_INT(MP_STREAM_POLL_ERR) },
{ MP_ROM_QSTR(MP_QSTR_POLLHUP), MP_ROM_INT(MP_STREAM_POLL_HUP) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_select_globals, mp_module_select_globals_table);
const mp_obj_module_t mp_module_select = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
};
MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_select, mp_module_select);
#endif // MICROPY_PY_SELECT

236
extmod/modtime.c Normal file
View File

@ -0,0 +1,236 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2023 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mphal.h"
#include "py/runtime.h"
#include "py/smallint.h"
#include "extmod/modtime.h"
#if MICROPY_PY_TIME
#ifdef MICROPY_PY_TIME_INCLUDEFILE
#include MICROPY_PY_TIME_INCLUDEFILE
#endif
#if MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME
#include "shared/timeutils/timeutils.h"
// localtime([secs])
// Convert a time expressed in seconds since the Epoch into an 8-tuple which
// contains: (year, month, mday, hour, minute, second, weekday, yearday)
// If secs is not provided or None, then the current time is used.
// - year is the full year, eg 2000
// - month is 1-12
// - mday is 1-31
// - hour is 0-23
// - minute is 0-59
// - second is 0-59
// - weekday is 0-6 for Mon-Sun
// - yearday is 1-366
STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
if (n_args == 0 || args[0] == mp_const_none) {
// Get current date and time.
return mp_time_localtime_get();
} else {
// Convert given seconds to tuple.
mp_int_t seconds = mp_obj_get_int(args[0]);
timeutils_struct_time_t tm;
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
mp_obj_t tuple[8] = {
tuple[0] = mp_obj_new_int(tm.tm_year),
tuple[1] = mp_obj_new_int(tm.tm_mon),
tuple[2] = mp_obj_new_int(tm.tm_mday),
tuple[3] = mp_obj_new_int(tm.tm_hour),
tuple[4] = mp_obj_new_int(tm.tm_min),
tuple[5] = mp_obj_new_int(tm.tm_sec),
tuple[6] = mp_obj_new_int(tm.tm_wday),
tuple[7] = mp_obj_new_int(tm.tm_yday),
};
return mp_obj_new_tuple(8, tuple);
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_time_localtime_obj, 0, 1, time_localtime);
// mktime()
// This is the inverse function of localtime. Its argument is a full 8-tuple
// which expresses a time as per localtime. It returns an integer which is
// the number of seconds since the Epoch (eg 1st Jan 1970, or 1st Jan 2000).
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
size_t len;
mp_obj_t *elem;
mp_obj_get_array(tuple, &len, &elem);
// localtime generates a tuple of len 8. CPython uses 9, so we accept both.
if (len < 8 || len > 9) {
mp_raise_TypeError(MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9"));
}
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_time_mktime_obj, time_mktime);
#endif // MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME
#if MICROPY_PY_TIME_TIME_TIME_NS
// time()
// Return the number of seconds since the Epoch.
STATIC mp_obj_t time_time(void) {
return mp_time_time_get();
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_time_time_obj, time_time);
// time_ns()
// Returns the number of nanoseconds since the Epoch, as an integer.
STATIC mp_obj_t time_time_ns(void) {
return mp_obj_new_int_from_ull(mp_hal_time_ns());
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_time_time_ns_obj, time_time_ns);
#endif // MICROPY_PY_TIME_TIME_TIME_NS
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
#ifdef MICROPY_PY_TIME_CUSTOM_SLEEP
mp_time_sleep(seconds_o);
#else
#if MICROPY_PY_BUILTINS_FLOAT
mp_hal_delay_ms((mp_uint_t)(1000 * mp_obj_get_float(seconds_o)));
#else
mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o));
#endif
#endif
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_time_sleep_obj, time_sleep);
STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) {
mp_int_t ms = mp_obj_get_int(arg);
if (ms >= 0) {
mp_hal_delay_ms(ms);
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_time_sleep_ms_obj, time_sleep_ms);
STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
mp_int_t us = mp_obj_get_int(arg);
if (us > 0) {
mp_hal_delay_us(us);
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_time_sleep_us_obj, time_sleep_us);
STATIC mp_obj_t time_ticks_ms(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_TIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_time_ticks_ms_obj, time_ticks_ms);
STATIC mp_obj_t time_ticks_us(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & (MICROPY_PY_TIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_time_ticks_us_obj, time_ticks_us);
STATIC mp_obj_t time_ticks_cpu(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & (MICROPY_PY_TIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_time_ticks_cpu_obj, time_ticks_cpu);
STATIC mp_obj_t time_ticks_diff(mp_obj_t end_in, mp_obj_t start_in) {
// we assume that the arguments come from ticks_xx so are small ints
mp_uint_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
mp_uint_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
// Optimized formula avoiding if conditions. We adjust difference "forward",
// wrap it around and adjust back.
mp_int_t diff = ((end - start + MICROPY_PY_TIME_TICKS_PERIOD / 2) & (MICROPY_PY_TIME_TICKS_PERIOD - 1))
- MICROPY_PY_TIME_TICKS_PERIOD / 2;
return MP_OBJ_NEW_SMALL_INT(diff);
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_time_ticks_diff_obj, time_ticks_diff);
STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) {
// we assume that first argument come from ticks_xx so is small int
mp_uint_t ticks = MP_OBJ_SMALL_INT_VALUE(ticks_in);
mp_uint_t delta = mp_obj_get_int(delta_in);
// Check that delta does not overflow the range that ticks_diff can handle.
// This ensures the following:
// - ticks_diff(ticks_add(T, delta), T) == delta
// - ticks_diff(T, ticks_add(T, delta)) == -delta
// The latter requires excluding delta=-TICKS_PERIOD/2.
//
// This unsigned comparison is equivalent to a signed comparison of:
// delta <= -TICKS_PERIOD/2 || delta >= TICKS_PERIOD/2
if (delta + MICROPY_PY_TIME_TICKS_PERIOD / 2 - 1 >= MICROPY_PY_TIME_TICKS_PERIOD - 1) {
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ticks interval overflow"));
}
return MP_OBJ_NEW_SMALL_INT((ticks + delta) & (MICROPY_PY_TIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_time_ticks_add_obj, time_ticks_add);
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
#if MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME
{ MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&mp_time_localtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mp_time_localtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mp_time_mktime_obj) },
#endif
#if MICROPY_PY_TIME_TIME_TIME_NS
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_time_time_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_time_time_ns_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_time_sleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_time_sleep_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_time_sleep_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_time_ticks_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_time_ticks_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_time_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_time_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_time_ticks_diff_obj) },
#ifdef MICROPY_PY_TIME_EXTRA_GLOBALS
MICROPY_PY_TIME_EXTRA_GLOBALS
#endif
};
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
const mp_obj_module_t mp_module_time = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_time_globals,
};
MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_time, mp_module_time);
#endif // MICROPY_PY_TIME

View File

@ -24,19 +24,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #ifndef MICROPY_INCLUDED_EXTMOD_MODUTIME_H
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #define MICROPY_INCLUDED_EXTMOD_MODUTIME_H
#include "py/obj.h" #include "py/obj.h"
MP_DECLARE_CONST_FUN_OBJ_1(mp_utime_sleep_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_time_mktime_obj);
MP_DECLARE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_time_sleep_obj);
MP_DECLARE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_time_sleep_ms_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_time_sleep_us_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_time_ticks_ms_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_time_ticks_us_obj);
MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_time_ticks_cpu_obj);
MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_time_ticks_diff_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_time_ns_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_time_ticks_add_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_time_time_ns_obj);
#endif // MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #endif // MICROPY_INCLUDED_EXTMOD_MODUTIME_H

View File

@ -582,7 +582,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
switch (op) { switch (op) {
case MP_UNARY_OP_INT: case MP_UNARY_OP_INT_MAYBE:
if (mp_obj_is_type(self->desc, &mp_type_tuple)) { if (mp_obj_is_type(self->desc, &mp_type_tuple)) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
@ -718,6 +718,8 @@ const mp_obj_module_t mp_module_uctypes = {
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals, .globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
}; };
// uctypes is not a Python standard library module (hence "uctypes"
// not "ctypes") and therefore shouldn't be extensible.
MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes); MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes);
#endif #endif

View File

@ -1,384 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Damien P. George
* Copyright (c) 2015-2017 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h"
#if MICROPY_PY_USELECT
#include <stdio.h>
#include "py/runtime.h"
#include "py/obj.h"
#include "py/objlist.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "shared/runtime/interrupt_char.h"
// Flags for poll()
#define FLAG_ONESHOT (1)
typedef struct _poll_obj_t {
mp_obj_t obj;
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
mp_uint_t flags;
mp_uint_t flags_ret;
} poll_obj_t;
STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_len, mp_uint_t flags, bool or_flags) {
for (mp_uint_t i = 0; i < obj_len; i++) {
mp_map_elem_t *elem = mp_map_lookup(poll_map, mp_obj_id(obj[i]), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
if (elem->value == MP_OBJ_NULL) {
// object not found; get its ioctl and add it to the poll list
const mp_stream_p_t *stream_p = mp_get_stream_raise(obj[i], MP_STREAM_OP_IOCTL);
poll_obj_t *poll_obj = m_new_obj(poll_obj_t);
poll_obj->obj = obj[i];
poll_obj->ioctl = stream_p->ioctl;
poll_obj->flags = flags;
poll_obj->flags_ret = 0;
elem->value = MP_OBJ_FROM_PTR(poll_obj);
} else {
// object exists; update its flags
if (or_flags) {
((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags |= flags;
} else {
((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags = flags;
}
}
}
}
// poll each object in the map
STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) {
mp_uint_t n_ready = 0;
for (mp_uint_t i = 0; i < poll_map->alloc; ++i) {
if (!mp_map_slot_is_filled(poll_map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map->table[i].value);
int errcode;
mp_int_t ret = poll_obj->ioctl(poll_obj->obj, MP_STREAM_POLL, poll_obj->flags, &errcode);
poll_obj->flags_ret = ret;
if (ret == -1) {
// error doing ioctl
mp_raise_OSError(errcode);
}
if (ret != 0) {
// object is ready
n_ready += 1;
if (rwx_num != NULL) {
if (ret & MP_STREAM_POLL_RD) {
rwx_num[0] += 1;
}
if (ret & MP_STREAM_POLL_WR) {
rwx_num[1] += 1;
}
if ((ret & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) {
rwx_num[2] += 1;
}
}
}
}
return n_ready;
}
#if MICROPY_PY_USELECT_SELECT
// select(rlist, wlist, xlist[, timeout])
STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
// get array data from tuple/list arguments
size_t rwx_len[3];
mp_obj_t *r_array, *w_array, *x_array;
mp_obj_get_array(args[0], &rwx_len[0], &r_array);
mp_obj_get_array(args[1], &rwx_len[1], &w_array);
mp_obj_get_array(args[2], &rwx_len[2], &x_array);
// get timeout
mp_uint_t timeout = -1;
if (n_args == 4) {
if (args[3] != mp_const_none) {
#if MICROPY_PY_BUILTINS_FLOAT
float timeout_f = mp_obj_get_float_to_f(args[3]);
if (timeout_f >= 0) {
timeout = (mp_uint_t)(timeout_f * 1000);
}
#else
timeout = mp_obj_get_int(args[3]) * 1000;
#endif
}
}
// merge separate lists and get the ioctl function for each object
mp_map_t poll_map;
mp_map_init(&poll_map, rwx_len[0] + rwx_len[1] + rwx_len[2]);
poll_map_add(&poll_map, r_array, rwx_len[0], MP_STREAM_POLL_RD, true);
poll_map_add(&poll_map, w_array, rwx_len[1], MP_STREAM_POLL_WR, true);
poll_map_add(&poll_map, x_array, rwx_len[2], MP_STREAM_POLL_ERR | MP_STREAM_POLL_HUP, true);
mp_uint_t start_tick = mp_hal_ticks_ms();
rwx_len[0] = rwx_len[1] = rwx_len[2] = 0;
for (;;) {
// poll the objects
mp_uint_t n_ready = poll_map_poll(&poll_map, rwx_len);
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
// one or more objects are ready, or we had a timeout
mp_obj_t list_array[3];
list_array[0] = mp_obj_new_list(rwx_len[0], NULL);
list_array[1] = mp_obj_new_list(rwx_len[1], NULL);
list_array[2] = mp_obj_new_list(rwx_len[2], NULL);
rwx_len[0] = rwx_len[1] = rwx_len[2] = 0;
for (mp_uint_t i = 0; i < poll_map.alloc; ++i) {
if (!mp_map_slot_is_filled(&poll_map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map.table[i].value);
if (poll_obj->flags_ret & MP_STREAM_POLL_RD) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[0]))->items[rwx_len[0]++] = poll_obj->obj;
}
if (poll_obj->flags_ret & MP_STREAM_POLL_WR) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[1]))->items[rwx_len[1]++] = poll_obj->obj;
}
if ((poll_obj->flags_ret & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) {
((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[2]))->items[rwx_len[2]++] = poll_obj->obj;
}
}
mp_map_deinit(&poll_map);
return mp_obj_new_tuple(3, list_array);
}
// CIRCUITPY
RUN_BACKGROUND_TASKS;
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_select_obj, 3, 4, select_select);
#endif // MICROPY_PY_USELECT_SELECT
typedef struct _mp_obj_poll_t {
mp_obj_base_t base;
mp_map_t poll_map;
short iter_cnt;
short iter_idx;
int flags;
// callee-owned tuple
mp_obj_t ret_tuple;
} mp_obj_poll_t;
// register(obj[, eventmask])
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t flags;
if (n_args == 3) {
flags = mp_obj_get_int(args[2]);
} else {
flags = MP_STREAM_POLL_RD | MP_STREAM_POLL_WR;
}
poll_map_add(&self->poll_map, &args[1], 1, flags, false);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register);
// unregister(obj)
STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
// TODO raise KeyError if obj didn't exist in map
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister);
// modify(obj, eventmask)
STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP);
if (elem == NULL) {
mp_raise_OSError(MP_ENOENT);
}
((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags = mp_obj_get_int(eventmask_in);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify);
STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
// work out timeout (its given already in ms)
mp_uint_t timeout = -1;
int flags = 0;
if (n_args >= 2) {
if (args[1] != mp_const_none) {
mp_int_t timeout_i = mp_obj_get_int(args[1]);
if (timeout_i >= 0) {
timeout = timeout_i;
}
}
if (n_args >= 3) {
flags = mp_obj_get_int(args[2]);
}
}
self->flags = flags;
mp_uint_t start_tick = mp_hal_ticks_ms();
mp_uint_t n_ready;
for (;;) {
// poll the objects
n_ready = poll_map_poll(&self->poll_map, NULL);
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
break;
}
// CIRCUITPY
RUN_BACKGROUND_TASKS;
if (mp_hal_is_interrupted()) {
return 0;
}
}
return n_ready;
}
STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t n_ready = poll_poll_internal(n_args, args);
// one or more objects are ready, or we had a timeout
mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL));
n_ready = 0;
for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) {
if (!mp_map_slot_is_filled(&self->poll_map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
if (poll_obj->flags_ret != 0) {
mp_obj_t tuple[2] = {poll_obj->obj, MP_OBJ_NEW_SMALL_INT(poll_obj->flags_ret)};
ret_list->items[n_ready++] = mp_obj_new_tuple(2, tuple);
if (self->flags & FLAG_ONESHOT) {
// Don't poll next time, until new event flags will be set explicitly
poll_obj->flags = 0;
}
}
}
return MP_OBJ_FROM_PTR(ret_list);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll);
STATIC mp_obj_t poll_ipoll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
if (self->ret_tuple == MP_OBJ_NULL) {
self->ret_tuple = mp_obj_new_tuple(2, NULL);
}
int n_ready = poll_poll_internal(n_args, args);
self->iter_cnt = n_ready;
self->iter_idx = 0;
return args[0];
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_ipoll_obj, 1, 3, poll_ipoll);
STATIC mp_obj_t poll_iternext(mp_obj_t self_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
if (self->iter_cnt == 0) {
return MP_OBJ_STOP_ITERATION;
}
self->iter_cnt--;
for (mp_uint_t i = self->iter_idx; i < self->poll_map.alloc; ++i) {
self->iter_idx++;
if (!mp_map_slot_is_filled(&self->poll_map, i)) {
continue;
}
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
if (poll_obj->flags_ret != 0) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple);
t->items[0] = poll_obj->obj;
t->items[1] = MP_OBJ_NEW_SMALL_INT(poll_obj->flags_ret);
if (self->flags & FLAG_ONESHOT) {
// Don't poll next time, until new event flags will be set explicitly
poll_obj->flags = 0;
}
return MP_OBJ_FROM_PTR(t);
}
}
assert(!"inconsistent number of poll active entries");
self->iter_cnt = 0;
return MP_OBJ_STOP_ITERATION;
}
STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) },
{ MP_ROM_QSTR(MP_QSTR_unregister), MP_ROM_PTR(&poll_unregister_obj) },
{ MP_ROM_QSTR(MP_QSTR_modify), MP_ROM_PTR(&poll_modify_obj) },
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&poll_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipoll), MP_ROM_PTR(&poll_ipoll_obj) },
};
STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_poll,
MP_QSTR_poll,
MP_TYPE_FLAG_ITER_IS_ITERNEXT,
iter, poll_iternext,
locals_dict, &poll_locals_dict
);
// poll()
STATIC mp_obj_t select_poll(void) {
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
mp_map_init(&poll->poll_map, 0);
poll->iter_cnt = 0;
poll->ret_tuple = MP_OBJ_NULL;
return MP_OBJ_FROM_PTR(poll);
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_select_poll_obj, select_poll);
STATIC const mp_rom_map_elem_t mp_module_select_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uselect) },
#if MICROPY_PY_USELECT_SELECT
{ MP_ROM_QSTR(MP_QSTR_select), MP_ROM_PTR(&mp_select_select_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mp_select_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_POLLIN), MP_ROM_INT(MP_STREAM_POLL_RD) },
{ MP_ROM_QSTR(MP_QSTR_POLLOUT), MP_ROM_INT(MP_STREAM_POLL_WR) },
{ MP_ROM_QSTR(MP_QSTR_POLLERR), MP_ROM_INT(MP_STREAM_POLL_ERR) },
{ MP_ROM_QSTR(MP_QSTR_POLLHUP), MP_ROM_INT(MP_STREAM_POLL_HUP) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_select_globals, mp_module_select_globals_table);
const mp_obj_module_t mp_module_uselect = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
};
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect);
#endif // MICROPY_PY_USELECT

View File

@ -31,10 +31,10 @@
#include "py/stream.h" #include "py/stream.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#if MICROPY_PY_UZLIB #if MICROPY_PY_ZLIB
#define UZLIB_CONF_PARANOID_CHECKS (1) #define UZLIB_CONF_PARANOID_CHECKS (1)
#include "lib/uzlib/tinf.h" #include "lib/uzlib/uzlib.h"
#if 0 // print debugging info #if 0 // print debugging info
#define DEBUG_printf DEBUG_printf #define DEBUG_printf DEBUG_printf
@ -243,4 +243,4 @@ MP_REGISTER_MODULE(MP_QSTR_zlib, mp_module_uzlib);
#include "lib/uzlib/adler32.c" #include "lib/uzlib/adler32.c"
#include "lib/uzlib/crc32.c" #include "lib/uzlib/crc32.c"
#endif // MICROPY_PY_UZLIB #endif // MICROPY_PY_ZLIB

View File

@ -1,121 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2016 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h"
#if MICROPY_PY_UTIME_MP_HAL
#include <string.h>
#include "py/obj.h"
#include "py/mphal.h"
#include "py/smallint.h"
#include "py/runtime.h"
#include "extmod/utime_mphal.h"
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
#if MICROPY_PY_BUILTINS_FLOAT
mp_hal_delay_ms((mp_uint_t)(1000 * mp_obj_get_float(seconds_o)));
#else
mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o));
#endif
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep);
STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) {
mp_int_t ms = mp_obj_get_int(arg);
if (ms >= 0) {
mp_hal_delay_ms(ms);
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms);
STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
mp_int_t us = mp_obj_get_int(arg);
if (us > 0) {
mp_hal_delay_us(us);
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us);
STATIC mp_obj_t time_ticks_ms(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj, time_ticks_ms);
STATIC mp_obj_t time_ticks_us(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj, time_ticks_us);
STATIC mp_obj_t time_ticks_cpu(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj, time_ticks_cpu);
STATIC mp_obj_t time_ticks_diff(mp_obj_t end_in, mp_obj_t start_in) {
// we assume that the arguments come from ticks_xx so are small ints
mp_uint_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
mp_uint_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
// Optimized formula avoiding if conditions. We adjust difference "forward",
// wrap it around and adjust back.
mp_int_t diff = ((end - start + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1))
- MICROPY_PY_UTIME_TICKS_PERIOD / 2;
return MP_OBJ_NEW_SMALL_INT(diff);
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff);
STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) {
// we assume that first argument come from ticks_xx so is small int
mp_uint_t ticks = MP_OBJ_SMALL_INT_VALUE(ticks_in);
mp_uint_t delta = mp_obj_get_int(delta_in);
// Check that delta does not overflow the range that ticks_diff can handle.
// This ensures the following:
// - ticks_diff(ticks_add(T, delta), T) == delta
// - ticks_diff(T, ticks_add(T, delta)) == -delta
// The latter requires excluding delta=-TICKS_PERIOD/2.
//
// This unsigned comparison is equivalent to a signed comparison of:
// delta <= -TICKS_PERIOD/2 || delta >= TICKS_PERIOD/2
if (delta + MICROPY_PY_UTIME_TICKS_PERIOD / 2 - 1 >= MICROPY_PY_UTIME_TICKS_PERIOD - 1) {
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ticks interval overflow"));
}
return MP_OBJ_NEW_SMALL_INT((ticks + delta) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add);
// Returns the number of nanoseconds since the Epoch, as an integer.
STATIC mp_obj_t time_time_ns(void) {
return mp_obj_new_int_from_ull(mp_hal_time_ns());
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_time_ns_obj, time_time_ns);
#endif // MICROPY_PY_UTIME_MP_HAL

View File

@ -365,7 +365,7 @@ mp_obj_t mp_vfs_getcwd(void) {
} }
MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd); MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd);
// CIRCUITPY: accessible from shared-module/os/__init__.c // CIRCUITPY-CHANGE: accessible from shared-module/os/__init__.c
mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) { mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) {
mp_vfs_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); mp_vfs_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in);
if (self->is_iter) { if (self->is_iter) {

View File

@ -93,13 +93,6 @@ STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t siz
return sz_out; return sz_out;
} }
STATIC mp_obj_t file_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;
return mp_stream_close(args[0]);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(file_obj___exit___obj, 4, 4, file_obj___exit__);
STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
pyb_file_obj_t *self = MP_OBJ_TO_PTR(o_in); pyb_file_obj_t *self = MP_OBJ_TO_PTR(o_in);
@ -162,9 +155,8 @@ STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&file_obj___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj) },
}; };
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table);
@ -265,7 +257,7 @@ STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_i
m_del_obj(pyb_file_obj_t, o); m_del_obj(pyb_file_obj_t, o);
mp_raise_OSError_errno_str(fresult_to_errno_table[res], path_in); mp_raise_OSError_errno_str(fresult_to_errno_table[res], path_in);
} }
// CIRCUITPY does fast seek. // CIRCUITPY-CHANGE: does fast seek.
// If we're reading, turn on fast seek. // If we're reading, turn on fast seek.
if (mode == FA_READ) { if (mode == FA_READ) {
// One call to determine how much space we need. // One call to determine how much space we need.

View File

@ -323,7 +323,7 @@ STATIC mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) {
size_t from = 1; size_t from = 1;
char *cwd = vstr_str(&self->cur_dir); char *cwd = vstr_str(&self->cur_dir);
while (from < CWD_LEN) { while (from < CWD_LEN) {
for (; cwd[from] == '/' && from < CWD_LEN; ++from) { for (; from < CWD_LEN && cwd[from] == '/'; ++from) {
// Scan for the start // Scan for the start
} }
if (from > to) { if (from > to) {
@ -331,7 +331,7 @@ STATIC mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) {
vstr_cut_out_bytes(&self->cur_dir, to, from - to); vstr_cut_out_bytes(&self->cur_dir, to, from - to);
from = to; from = to;
} }
for (; cwd[from] != '/' && from < CWD_LEN; ++from) { for (; from < CWD_LEN && cwd[from] != '/'; ++from) {
// Scan for the next / // Scan for the next /
} }
if ((from - to) == 1 && cwd[to] == '.') { if ((from - to) == 1 && cwd[to] == '.') {

View File

@ -123,12 +123,6 @@ mp_obj_t MP_VFS_LFSx(file_open)(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mod
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC mp_obj_t MP_VFS_LFSx(file___exit__)(size_t n_args, const mp_obj_t *args) {
(void)n_args;
return mp_stream_close(args[0]);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(MP_VFS_LFSx(file___exit___obj), 4, 4, MP_VFS_LFSx(file___exit__));
STATIC mp_uint_t MP_VFS_LFSx(file_read)(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t MP_VFS_LFSx(file_read)(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
MP_OBJ_VFS_LFSx_FILE *self = MP_OBJ_TO_PTR(self_in); MP_OBJ_VFS_LFSx_FILE *self = MP_OBJ_TO_PTR(self_in);
MP_VFS_LFSx(check_open)(self); MP_VFS_LFSx(check_open)(self);
@ -213,7 +207,7 @@ STATIC const mp_rom_map_elem_t MP_VFS_LFSx(file_locals_dict_table)[] = {
{ MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&MP_VFS_LFSx(file___exit___obj)) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(MP_VFS_LFSx(file_locals_dict), MP_VFS_LFSx(file_locals_dict_table)); STATIC MP_DEFINE_CONST_DICT(MP_VFS_LFSx(file_locals_dict), MP_VFS_LFSx(file_locals_dict_table));

View File

@ -332,7 +332,7 @@ STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat); STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
#if MICROPY_PY_UOS_STATVFS #if MICROPY_PY_OS_STATVFS
#ifdef __ANDROID__ #ifdef __ANDROID__
#define USE_STATFS 1 #define USE_STATFS 1
@ -390,7 +390,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) }, { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) }, { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) }, { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
#if MICROPY_PY_UOS_STATVFS #if MICROPY_PY_OS_STATVFS
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) }, { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
#endif #endif
}; };

View File

@ -115,12 +115,6 @@ STATIC mp_obj_t vfs_posix_file_fileno(mp_obj_t self_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_file_fileno_obj, vfs_posix_file_fileno); STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_file_fileno_obj, vfs_posix_file_fileno);
STATIC mp_obj_t vfs_posix_file___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;
return mp_stream_close(args[0]);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(vfs_posix_file___exit___obj, 4, 4, vfs_posix_file___exit__);
STATIC mp_uint_t vfs_posix_file_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t vfs_posix_file_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
mp_obj_vfs_posix_file_t *o = MP_OBJ_TO_PTR(o_in); mp_obj_vfs_posix_file_t *o = MP_OBJ_TO_PTR(o_in);
check_fd_is_open(o); check_fd_is_open(o);
@ -159,12 +153,20 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
switch (request) { switch (request) {
case MP_STREAM_FLUSH: { case MP_STREAM_FLUSH: {
int ret; int ret;
// fsync(stdin/stdout/stderr) may fail with EINVAL (or ENOTSUP on macos or EBADF
// on windows), because the OS doesn't buffer these except for instance when they
// are redirected from/to file, but don't propagate that error out. Because data
// is not buffered by us, and stdin/out/err.flush() should just be a no-op.
#if defined(__APPLE__)
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
#elif defined(_MSC_VER)
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == EBADF)
#else
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
#endif
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), { MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
if (err == EINVAL if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) { && (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
// fsync(stdin/stdout/stderr) may fail with EINVAL, but don't propagate that
// error out. Because data is not buffered by us, and stdin/out/err.flush()
// should just be a no-op.
return 0; return 0;
} }
*errcode = err; *errcode = err;
@ -194,7 +196,7 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
return 0; return 0;
case MP_STREAM_GET_FILENO: case MP_STREAM_GET_FILENO:
return o->fd; return o->fd;
#if MICROPY_PY_USELECT #if MICROPY_PY_SELECT && !MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
case MP_STREAM_POLL: { case MP_STREAM_POLL: {
#ifdef _WIN32 #ifdef _WIN32
mp_raise_NotImplementedError(MP_ERROR_TEXT("poll on file not available on win32")); mp_raise_NotImplementedError(MP_ERROR_TEXT("poll on file not available on win32"));
@ -215,6 +217,15 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
if (pfd.revents & POLLOUT) { if (pfd.revents & POLLOUT) {
ret |= MP_STREAM_POLL_WR; ret |= MP_STREAM_POLL_WR;
} }
if (pfd.revents & POLLERR) {
ret |= MP_STREAM_POLL_ERR;
}
if (pfd.revents & POLLHUP) {
ret |= MP_STREAM_POLL_HUP;
}
if (pfd.revents & POLLNVAL) {
ret |= MP_STREAM_POLL_NVAL;
}
} }
return ret; return ret;
#endif #endif
@ -239,7 +250,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&vfs_posix_file___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(vfs_posix_rawfile_locals_dict, vfs_posix_rawfile_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(vfs_posix_rawfile_locals_dict, vfs_posix_rawfile_locals_dict_table);
@ -266,12 +277,58 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = {
.is_text = true, .is_text = true,
}; };
#if MICROPY_PY_SYS_STDIO_BUFFER
const mp_obj_vfs_posix_file_t mp_sys_stdin_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDIN_FILENO};
const mp_obj_vfs_posix_file_t mp_sys_stdout_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDOUT_FILENO};
const mp_obj_vfs_posix_file_t mp_sys_stderr_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDERR_FILENO};
// Forward declarations.
const mp_obj_vfs_posix_file_t mp_sys_stdin_obj;
const mp_obj_vfs_posix_file_t mp_sys_stdout_obj;
const mp_obj_vfs_posix_file_t mp_sys_stderr_obj;
STATIC void vfs_posix_textio_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] != MP_OBJ_NULL) {
// These objects are read-only.
return;
}
if (attr == MP_QSTR_buffer) {
// Implement the `buffer` attribute only on std{in,out,err} instances.
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stdin_obj) {
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stdin_buffer_obj);
return;
}
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stdout_obj) {
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stdout_buffer_obj);
return;
}
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stderr_obj) {
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stderr_buffer_obj);
return;
}
}
// Any other attribute - forward to locals dict.
dest[1] = MP_OBJ_SENTINEL;
};
#define VFS_POSIX_TEXTIO_TYPE_ATTR attr, vfs_posix_textio_attr,
#else
#define VFS_POSIX_TEXTIO_TYPE_ATTR
#endif // MICROPY_PY_SYS_STDIO_BUFFER
MP_DEFINE_CONST_OBJ_TYPE( MP_DEFINE_CONST_OBJ_TYPE(
mp_type_vfs_posix_textio, mp_type_vfs_posix_textio,
MP_QSTR_TextIOWrapper, MP_QSTR_TextIOWrapper,
MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_FLAG_ITER_IS_STREAM,
print, vfs_posix_file_print, print, vfs_posix_file_print,
protocol, &vfs_posix_textio_stream_p, protocol, &vfs_posix_textio_stream_p,
VFS_POSIX_TEXTIO_TYPE_ATTR
locals_dict, &vfs_posix_rawfile_locals_dict locals_dict, &vfs_posix_rawfile_locals_dict
); );

@ -1 +1 @@
Subproject commit 1bc2c9cb8b8fe4659bd94b8ebba5a4c02029b7fa Subproject commit 981743de6fcdbe672e482b6fd724d31d0a0d2476

View File

@ -110,7 +110,7 @@ void mbedtls_strerror(int ret, char *buf, size_t buflen) {
if (got_hl) { if (got_hl) {
use_ret = ret & 0xFF80; use_ret = ret & 0xFF80;
// special case // special case, don't try to translate low level code
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);

View File

@ -0,0 +1,710 @@
/*
* Error message information
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#if defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
#endif
#if defined(MBEDTLS_ARC4_C)
#include "mbedtls/arc4.h"
#endif
#if defined(MBEDTLS_ARIA_C)
#include "mbedtls/aria.h"
#endif
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
#endif
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#endif
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
#if defined(MBEDTLS_BLOWFISH_C)
#include "mbedtls/blowfish.h"
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#include "mbedtls/camellia.h"
#endif
#if defined(MBEDTLS_CCM_C)
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#endif
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#endif
#if defined(MBEDTLS_DES_C)
#include "mbedtls/des.h"
#endif
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
#if defined(MBEDTLS_HKDF_C)
#include "mbedtls/hkdf.h"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#endif
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_NET_C)
#include "mbedtls/net_sockets.h"
#endif
#if defined(MBEDTLS_OID_C)
#include "mbedtls/oid.h"
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "mbedtls/padlock.h"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk.h"
#endif
#if defined(MBEDTLS_PKCS12_C)
#include "mbedtls/pkcs12.h"
#endif
#if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#endif
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C)
#include "mbedtls/ssl.h"
#endif
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#endif
#if defined(MBEDTLS_XTEA_C)
#include "mbedtls/xtea.h"
#endif
// Error code table type
struct ssl_errs {
int16_t errnum;
const char *errstr;
};
// Table of high level error codes
static const struct ssl_errs mbedtls_high_level_error_tab[] = {
// BEGIN generated code
#if defined(MBEDTLS_CIPHER_C)
{ -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE), "CIPHER_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA), "CIPHER_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED), "CIPHER_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_CIPHER_INVALID_PADDING), "CIPHER_INVALID_PADDING" },
{ -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED), "CIPHER_FULL_BLOCK_EXPECTED" },
{ -(MBEDTLS_ERR_CIPHER_AUTH_FAILED), "CIPHER_AUTH_FAILED" },
{ -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT), "CIPHER_INVALID_CONTEXT" },
{ -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED), "CIPHER_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
{ -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA), "DHM_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED), "DHM_READ_PARAMS_FAILED" },
{ -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED), "DHM_MAKE_PARAMS_FAILED" },
{ -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED), "DHM_READ_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED), "DHM_MAKE_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED), "DHM_CALC_SECRET_FAILED" },
{ -(MBEDTLS_ERR_DHM_INVALID_FORMAT), "DHM_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_DHM_ALLOC_FAILED), "DHM_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_DHM_FILE_IO_ERROR), "DHM_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED), "DHM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED), "DHM_SET_GROUP_FAILED" },
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
{ -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA), "ECP_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL), "ECP_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE), "ECP_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_ECP_VERIFY_FAILED), "ECP_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_ECP_ALLOC_FAILED), "ECP_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_ECP_RANDOM_FAILED), "ECP_RANDOM_FAILED" },
{ -(MBEDTLS_ERR_ECP_INVALID_KEY), "ECP_INVALID_KEY" },
{ -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH), "ECP_SIG_LEN_MISMATCH" },
{ -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED), "ECP_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_ECP_IN_PROGRESS), "ECP_IN_PROGRESS" },
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
{ -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE), "MD_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_MD_BAD_INPUT_DATA), "MD_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_MD_ALLOC_FAILED), "MD_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_MD_FILE_IO_ERROR), "MD_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED), "MD_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
{ -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT), "PEM_NO_HEADER_FOOTER_PRESENT" },
{ -(MBEDTLS_ERR_PEM_INVALID_DATA), "PEM_INVALID_DATA" },
{ -(MBEDTLS_ERR_PEM_ALLOC_FAILED), "PEM_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_PEM_INVALID_ENC_IV), "PEM_INVALID_ENC_IV" },
{ -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG), "PEM_UNKNOWN_ENC_ALG" },
{ -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED), "PEM_PASSWORD_REQUIRED" },
{ -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH), "PEM_PASSWORD_MISMATCH" },
{ -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE), "PEM_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA), "PEM_BAD_INPUT_DATA" },
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
{ -(MBEDTLS_ERR_PK_ALLOC_FAILED), "PK_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_PK_TYPE_MISMATCH), "PK_TYPE_MISMATCH" },
{ -(MBEDTLS_ERR_PK_BAD_INPUT_DATA), "PK_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PK_FILE_IO_ERROR), "PK_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION), "PK_KEY_INVALID_VERSION" },
{ -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT), "PK_KEY_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG), "PK_UNKNOWN_PK_ALG" },
{ -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED), "PK_PASSWORD_REQUIRED" },
{ -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH), "PK_PASSWORD_MISMATCH" },
{ -(MBEDTLS_ERR_PK_INVALID_PUBKEY), "PK_INVALID_PUBKEY" },
{ -(MBEDTLS_ERR_PK_INVALID_ALG), "PK_INVALID_ALG" },
{ -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE), "PK_UNKNOWN_NAMED_CURVE" },
{ -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE), "PK_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH), "PK_SIG_LEN_MISMATCH" },
{ -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED), "PK_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
{ -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA), "PKCS12_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE), "PKCS12_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT), "PKCS12_PBE_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH), "PKCS12_PASSWORD_MISMATCH" },
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
{ -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA), "PKCS5_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT), "PKCS5_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE), "PKCS5_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH), "PKCS5_PASSWORD_MISMATCH" },
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
{ -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA), "RSA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_RSA_INVALID_PADDING), "RSA_INVALID_PADDING" },
{ -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED), "RSA_KEY_GEN_FAILED" },
{ -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED), "RSA_KEY_CHECK_FAILED" },
{ -(MBEDTLS_ERR_RSA_PUBLIC_FAILED), "RSA_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_RSA_PRIVATE_FAILED), "RSA_PRIVATE_FAILED" },
{ -(MBEDTLS_ERR_RSA_VERIFY_FAILED), "RSA_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE), "RSA_OUTPUT_TOO_LARGE" },
{ -(MBEDTLS_ERR_RSA_RNG_FAILED), "RSA_RNG_FAILED" },
{ -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION), "RSA_UNSUPPORTED_OPERATION" },
{ -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED), "RSA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
{ -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE), "SSL_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA), "SSL_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_SSL_INVALID_MAC), "SSL_INVALID_MAC" },
{ -(MBEDTLS_ERR_SSL_INVALID_RECORD), "SSL_INVALID_RECORD" },
{ -(MBEDTLS_ERR_SSL_CONN_EOF), "SSL_CONN_EOF" },
{ -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER), "SSL_UNKNOWN_CIPHER" },
{ -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN), "SSL_NO_CIPHER_CHOSEN" },
{ -(MBEDTLS_ERR_SSL_NO_RNG), "SSL_NO_RNG" },
{ -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE), "SSL_NO_CLIENT_CERTIFICATE" },
{ -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE), "SSL_CERTIFICATE_TOO_LARGE" },
{ -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED), "SSL_CERTIFICATE_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED), "SSL_PRIVATE_KEY_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED), "SSL_CA_CHAIN_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE), "SSL_UNEXPECTED_MESSAGE" },
{ -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED), "SSL_PEER_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY), "SSL_PEER_CLOSE_NOTIFY" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), "SSL_BAD_HS_CLIENT_HELLO" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO), "SSL_BAD_HS_SERVER_HELLO" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE), "SSL_BAD_HS_CERTIFICATE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST), "SSL_BAD_HS_CERTIFICATE_REQUEST" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE), "SSL_BAD_HS_SERVER_KEY_EXCHANGE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE), "SSL_BAD_HS_SERVER_HELLO_DONE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY), "SSL_BAD_HS_CERTIFICATE_VERIFY" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC), "SSL_BAD_HS_CHANGE_CIPHER_SPEC" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED), "SSL_BAD_HS_FINISHED" },
{ -(MBEDTLS_ERR_SSL_ALLOC_FAILED), "SSL_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED), "SSL_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH), "SSL_HW_ACCEL_FALLTHROUGH" },
{ -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED), "SSL_COMPRESSION_FAILED" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION), "SSL_BAD_HS_PROTOCOL_VERSION" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET), "SSL_BAD_HS_NEW_SESSION_TICKET" },
{ -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED), "SSL_SESSION_TICKET_EXPIRED" },
{ -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH), "SSL_PK_TYPE_MISMATCH" },
{ -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY), "SSL_UNKNOWN_IDENTITY" },
{ -(MBEDTLS_ERR_SSL_INTERNAL_ERROR), "SSL_INTERNAL_ERROR" },
{ -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING), "SSL_COUNTER_WRAPPING" },
{ -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO), "SSL_WAITING_SERVER_HELLO_RENEGO" },
{ -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED), "SSL_HELLO_VERIFY_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL), "SSL_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE), "SSL_NO_USABLE_CIPHERSUITE" },
{ -(MBEDTLS_ERR_SSL_WANT_READ), "SSL_WANT_READ" },
{ -(MBEDTLS_ERR_SSL_WANT_WRITE), "SSL_WANT_WRITE" },
{ -(MBEDTLS_ERR_SSL_TIMEOUT), "SSL_TIMEOUT" },
{ -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT), "SSL_CLIENT_RECONNECT" },
{ -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD), "SSL_UNEXPECTED_RECORD" },
{ -(MBEDTLS_ERR_SSL_NON_FATAL), "SSL_NON_FATAL" },
{ -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH), "SSL_INVALID_VERIFY_HASH" },
{ -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" },
{ -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" },
{ -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" },
{ -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" },
{ -(MBEDTLS_ERR_SSL_BAD_CONFIG), "SSL_BAD_CONFIG" },
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
{ -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE), "X509_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_OID), "X509_UNKNOWN_OID" },
{ -(MBEDTLS_ERR_X509_INVALID_FORMAT), "X509_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_X509_INVALID_VERSION), "X509_INVALID_VERSION" },
{ -(MBEDTLS_ERR_X509_INVALID_SERIAL), "X509_INVALID_SERIAL" },
{ -(MBEDTLS_ERR_X509_INVALID_ALG), "X509_INVALID_ALG" },
{ -(MBEDTLS_ERR_X509_INVALID_NAME), "X509_INVALID_NAME" },
{ -(MBEDTLS_ERR_X509_INVALID_DATE), "X509_INVALID_DATE" },
{ -(MBEDTLS_ERR_X509_INVALID_SIGNATURE), "X509_INVALID_SIGNATURE" },
{ -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS), "X509_INVALID_EXTENSIONS" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_VERSION), "X509_UNKNOWN_VERSION" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG), "X509_UNKNOWN_SIG_ALG" },
{ -(MBEDTLS_ERR_X509_SIG_MISMATCH), "X509_SIG_MISMATCH" },
{ -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED), "X509_CERT_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT), "X509_CERT_UNKNOWN_FORMAT" },
{ -(MBEDTLS_ERR_X509_BAD_INPUT_DATA), "X509_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_X509_ALLOC_FAILED), "X509_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_X509_FILE_IO_ERROR), "X509_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL), "X509_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_X509_FATAL_ERROR), "X509_FATAL_ERROR" },
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code
};
static const struct ssl_errs mbedtls_low_level_error_tab[] = {
// Low level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_AES_C)
{ -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH), "AES_INVALID_KEY_LENGTH" },
{ -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH), "AES_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_AES_BAD_INPUT_DATA), "AES_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE), "AES_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED), "AES_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
{ -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED), "ARC4_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
{ -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA), "ARIA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH), "ARIA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE), "ARIA_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED), "ARIA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
{ -(MBEDTLS_ERR_ASN1_OUT_OF_DATA), "ASN1_OUT_OF_DATA" },
{ -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG), "ASN1_UNEXPECTED_TAG" },
{ -(MBEDTLS_ERR_ASN1_INVALID_LENGTH), "ASN1_INVALID_LENGTH" },
{ -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH), "ASN1_LENGTH_MISMATCH" },
{ -(MBEDTLS_ERR_ASN1_INVALID_DATA), "ASN1_INVALID_DATA" },
{ -(MBEDTLS_ERR_ASN1_ALLOC_FAILED), "ASN1_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL), "ASN1_BUF_TOO_SMALL" },
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
{ -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL), "BASE64_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER), "BASE64_INVALID_CHARACTER" },
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
{ -(MBEDTLS_ERR_MPI_FILE_IO_ERROR), "MPI_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA), "MPI_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_MPI_INVALID_CHARACTER), "MPI_INVALID_CHARACTER" },
{ -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL), "MPI_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE), "MPI_NEGATIVE_VALUE" },
{ -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO), "MPI_DIVISION_BY_ZERO" },
{ -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE), "MPI_NOT_ACCEPTABLE" },
{ -(MBEDTLS_ERR_MPI_ALLOC_FAILED), "MPI_ALLOC_FAILED" },
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
{ -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA), "BLOWFISH_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH), "BLOWFISH_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED), "BLOWFISH_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
{ -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA), "CAMELLIA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH), "CAMELLIA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED), "CAMELLIA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
{ -(MBEDTLS_ERR_CCM_BAD_INPUT), "CCM_BAD_INPUT" },
{ -(MBEDTLS_ERR_CCM_AUTH_FAILED), "CCM_AUTH_FAILED" },
{ -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED), "CCM_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
{ -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA), "CHACHA20_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE), "CHACHA20_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED), "CHACHA20_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
{ -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE), "CHACHAPOLY_BAD_STATE" },
{ -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED), "CHACHAPOLY_AUTH_FAILED" },
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
{ -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED), "CMAC_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
{ -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED), "CTR_DRBG_ENTROPY_SOURCE_FAILED" },
{ -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG), "CTR_DRBG_REQUEST_TOO_BIG" },
{ -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG), "CTR_DRBG_INPUT_TOO_BIG" },
{ -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR), "CTR_DRBG_FILE_IO_ERROR" },
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
{ -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH), "DES_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED), "DES_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
{ -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED), "ENTROPY_SOURCE_FAILED" },
{ -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES), "ENTROPY_MAX_SOURCES" },
{ -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED), "ENTROPY_NO_SOURCES_DEFINED" },
{ -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE), "ENTROPY_NO_STRONG_SOURCE" },
{ -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" },
#endif /* MBEDTLS_ENTROPY_C */
#if defined(MBEDTLS_GCM_C)
{ -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" },
{ -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_GCM_BAD_INPUT), "GCM_BAD_INPUT" },
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
{ -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA), "HKDF_BAD_INPUT_DATA" },
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
{ -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG), "HMAC_DRBG_REQUEST_TOO_BIG" },
{ -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG), "HMAC_DRBG_INPUT_TOO_BIG" },
{ -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR), "HMAC_DRBG_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED), "HMAC_DRBG_ENTROPY_SOURCE_FAILED" },
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
{ -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED), "MD2_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
{ -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED), "MD4_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
{ -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED), "MD5_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
{ -(MBEDTLS_ERR_NET_SOCKET_FAILED), "NET_SOCKET_FAILED" },
{ -(MBEDTLS_ERR_NET_CONNECT_FAILED), "NET_CONNECT_FAILED" },
{ -(MBEDTLS_ERR_NET_BIND_FAILED), "NET_BIND_FAILED" },
{ -(MBEDTLS_ERR_NET_LISTEN_FAILED), "NET_LISTEN_FAILED" },
{ -(MBEDTLS_ERR_NET_ACCEPT_FAILED), "NET_ACCEPT_FAILED" },
{ -(MBEDTLS_ERR_NET_RECV_FAILED), "NET_RECV_FAILED" },
{ -(MBEDTLS_ERR_NET_SEND_FAILED), "NET_SEND_FAILED" },
{ -(MBEDTLS_ERR_NET_CONN_RESET), "NET_CONN_RESET" },
{ -(MBEDTLS_ERR_NET_UNKNOWN_HOST), "NET_UNKNOWN_HOST" },
{ -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL), "NET_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_NET_INVALID_CONTEXT), "NET_INVALID_CONTEXT" },
{ -(MBEDTLS_ERR_NET_POLL_FAILED), "NET_POLL_FAILED" },
{ -(MBEDTLS_ERR_NET_BAD_INPUT_DATA), "NET_BAD_INPUT_DATA" },
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
{ -(MBEDTLS_ERR_OID_NOT_FOUND), "OID_NOT_FOUND" },
{ -(MBEDTLS_ERR_OID_BUF_TOO_SMALL), "OID_BUF_TOO_SMALL" },
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
{ -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED), "PADLOCK_DATA_MISALIGNED" },
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_PLATFORM_C)
{ -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED), "PLATFORM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED), "PLATFORM_FEATURE_UNSUPPORTED" },
#endif /* MBEDTLS_PLATFORM_C */
#if defined(MBEDTLS_POLY1305_C)
{ -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA), "POLY1305_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE), "POLY1305_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED), "POLY1305_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
{ -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED), "RIPEMD160_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
{ -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED), "SHA1_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA), "SHA1_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{ -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED), "SHA256_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA), "SHA256_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{ -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED), "SHA512_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA), "SHA512_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
{ -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE), "THREADING_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA), "THREADING_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_THREADING_MUTEX_ERROR), "THREADING_MUTEX_ERROR" },
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
{ -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH), "XTEA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED), "XTEA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_XTEA_C */
// END generated code
};
static const char *mbedtls_err_prefix = "MBEDTLS_ERR_";
#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 )
// copy error text into buffer, ensure null termination, return strlen of result
static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) {
if (buflen == 0) return 0;
// prefix for all error names
strncpy(buf, mbedtls_err_prefix, buflen);
if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) {
buf[buflen-1] = 0;
return buflen-1;
}
// append error name from table
for (int i = 0; i < tab_len; i++) {
if (tab[i].errnum == err) {
strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN);
buf[buflen-1] = 0;
return strlen(buf);
}
}
mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)",
err);
return strlen(buf);
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void mbedtls_strerror(int ret, char *buf, size_t buflen) {
int use_ret;
if (buflen == 0) return;
buf[buflen-1] = 0;
if (ret < 0) ret = -ret;
//
// High-level error codes
//
uint8_t got_hl = (ret & 0xFF80) != 0;
if (got_hl) {
use_ret = ret & 0xFF80;
// special case
#if defined(MBEDTLS_SSL_TLS_C)
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);
buf[buflen-1] = 0;
return;
}
#endif
size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab,
ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen);
buf += len;
buflen -= len;
if (buflen == 0) return;
}
//
// Low-level error codes
//
use_ret = ret & ~0xFF80;
if (use_ret == 0) return;
// If high level code is present, make a concatenation between both error strings.
if (got_hl) {
if (buflen < 2) return;
*buf++ = '+';
buflen--;
}
mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab,
ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen);
}
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */

View File

@ -1,22 +1,29 @@
--- generate_errors_orig.pl 2020-06-20 08:40:38.819060379 -0700 --- generate_errors_orig.pl 2023-04-30 17:58:23.503070758 +1000
+++ generate_errors.pl 2020-06-20 08:47:26.511163591 -0700 +++ generate_errors.py 2023-04-30 17:58:20.826338349 +1000
@@ -162,16 +162,12 @@ @@ -162,7 +162,7 @@
if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
{ {
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n". $code_check = \$ll_code_check;
- "${white_space}\{\n". $old_define = \$ll_old_define;
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n". - $white_space = ' ';
- "${white_space} return;\n". + $white_space = ' ';
- "${white_space}}\n"
+ # no-op, this case is hard-coded in error.fmt
} }
else else
{ {
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n". @@ -203,8 +203,15 @@
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n" ${$old_define} = $define_name;
+ my $error_text = $error_name =~ s/^MBEDTLS_ERR_//r;
+ ${$code_check} .= "${white_space}{ -($error_name), \"$error_text\" },\n"
} }
- ${$code_check} .= "${white_space}case -($error_name):\n".
- "${white_space} return( \"$module_name - $description\" );\n"
+ if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
+ {
+ # no-op, this case is hard-coded in error.fmt
+ }
+ else
+ {
+ my $error_text = $error_name =~ s/^MBEDTLS_ERR_//r;
+ ${$code_check} .= "${white_space}{ -($error_name), \"$error_text\" },\n"
+ }
}; };
if ($ll_old_define ne "")

View File

@ -53,6 +53,10 @@
#include "mbedtls/aria.h" #include "mbedtls/aria.h"
#endif #endif
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
#endif
#if defined(MBEDTLS_BASE64_C) #if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h" #include "mbedtls/base64.h"
#endif #endif
@ -109,6 +113,10 @@
#include "mbedtls/entropy.h" #include "mbedtls/entropy.h"
#endif #endif
#if defined(MBEDTLS_ERROR_C)
#include "mbedtls/error.h"
#endif
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h" #include "mbedtls/gcm.h"
#endif #endif
@ -377,7 +385,10 @@ static const struct ssl_errs mbedtls_high_level_error_tab[] = {
{ -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" }, { -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" },
{ -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" }, { -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" },
{ -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" }, { -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" },
{ -(MBEDTLS_ERR_SSL_UNEXPECTED_CID), "SSL_UNEXPECTED_CID" },
{ -(MBEDTLS_ERR_SSL_VERSION_MISMATCH), "SSL_VERSION_MISMATCH" },
{ -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" }, { -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" },
{ -(MBEDTLS_ERR_SSL_BAD_CONFIG), "SSL_BAD_CONFIG" },
#endif /* MBEDTLS_SSL_TLS_C */ #endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
@ -507,6 +518,11 @@ static const struct ssl_errs mbedtls_low_level_error_tab[] = {
{ -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" }, { -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" },
#endif /* MBEDTLS_ENTROPY_C */ #endif /* MBEDTLS_ENTROPY_C */
#if defined(MBEDTLS_ERROR_C)
{ -(MBEDTLS_ERR_ERROR_GENERIC_ERROR), "ERROR_GENERIC_ERROR" },
{ -(MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED), "ERROR_CORRUPTION_DETECTED" },
#endif /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
{ -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" }, { -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" },
{ -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" }, { -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" },
@ -650,7 +666,7 @@ void mbedtls_strerror(int ret, char *buf, size_t buflen) {
if (got_hl) { if (got_hl) {
use_ret = ret & 0xFF80; use_ret = ret & 0xFF80;
// special case // special case, don't try to translate low level code
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);

@ -1 +1 @@
Subproject commit e6b89eafa3b86d2e8e405450377d459600a30cd6 Subproject commit e025c843b60e93689f0f991d753010bb5bd6a722

View File

@ -2834,7 +2834,7 @@ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not
if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */
lfn[di++] = wc; /* Store the Unicode character */ lfn[di++] = wc; /* Store the Unicode character */
} }
while (*p == '/' || *p == '\\') p++; /* Skip duplicated separators if exist */ if (wc == '/' || wc == '\\') while (*p == '/' || *p == '\\') p++; /* Skip duplicated separators if exist */
*path = p; /* Return pointer to the next segment */ *path = p; /* Return pointer to the next segment */
cf = (wc < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ cf = (wc < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */

View File

@ -254,7 +254,7 @@ int re1_5_compilecode(ByteProg *prog, const char *re)
return 0; return 0;
} }
// CIRCUITPY debug as main program // CIRCUITPY-CHANGE: debug as main program
#if defined(DEBUG_COMPILECODE) #if defined(DEBUG_COMPILECODE)
#include <assert.h> #include <assert.h>
void re1_5_fatal(char *x) { void re1_5_fatal(char *x) {

View File

@ -395,15 +395,7 @@ msgid "'await' outside function"
msgstr "" msgstr ""
#: py/compile.c #: py/compile.c
msgid "'await', 'async for' or 'async with' outside async function" msgid "'break'/'continue' outside loop"
msgstr ""
#: py/compile.c
msgid "'break' outside loop"
msgstr ""
#: py/compile.c
msgid "'continue' outside loop"
msgstr "" msgstr ""
#: py/compile.c #: py/compile.c
@ -965,7 +957,7 @@ msgstr ""
msgid "EXTINT channel already in use" msgid "EXTINT channel already in use"
msgstr "" msgstr ""
#: extmod/modure.c #: extmod/modre.c
msgid "Error in regex" msgid "Error in regex"
msgstr "" msgstr ""
@ -1045,7 +1037,7 @@ msgstr ""
msgid "Failed to write internal flash." msgid "Failed to write internal flash."
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "File exists" msgid "File exists"
msgstr "" msgstr ""
@ -1180,7 +1172,7 @@ msgstr ""
msgid "Input taking too long" msgid "Input taking too long"
msgstr "" msgstr ""
#: ports/espressif/common-hal/neopixel_write/__init__.c py/moduerrno.c #: ports/espressif/common-hal/neopixel_write/__init__.c py/moderrno.c
msgid "Input/output error" msgid "Input/output error"
msgstr "" msgstr ""
@ -1259,7 +1251,7 @@ msgstr ""
msgid "Invalid MAC address" msgid "Invalid MAC address"
msgstr "" msgstr ""
#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c
msgid "Invalid argument" msgid "Invalid argument"
msgstr "" msgstr ""
@ -1525,15 +1517,15 @@ msgstr ""
msgid "No pulldown on pin; 1Mohm recommended" msgid "No pulldown on pin; 1Mohm recommended"
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "No space left on device" msgid "No space left on device"
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "No such device" msgid "No such device"
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "No such file/directory" msgid "No such file/directory"
msgstr "" msgstr ""
@ -1654,7 +1646,7 @@ msgstr ""
msgid "Only one color can be transparent at a time" msgid "Only one color can be transparent at a time"
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "Operation not permitted" msgid "Operation not permitted"
msgstr "" msgstr ""
@ -1708,7 +1700,7 @@ msgstr ""
msgid "Peripheral in use" msgid "Peripheral in use"
msgstr "" msgstr ""
#: py/moduerrno.c #: py/moderrno.c
msgid "Permission denied" msgid "Permission denied"
msgstr "" msgstr ""
@ -1842,7 +1834,7 @@ msgstr ""
msgid "Read-only" msgid "Read-only"
msgstr "" msgstr ""
#: extmod/vfs_fat.c py/moduerrno.c #: extmod/vfs_fat.c py/moderrno.c
msgid "Read-only filesystem" msgid "Read-only filesystem"
msgstr "" msgstr ""
@ -2403,7 +2395,7 @@ msgstr ""
msgid "__new__ arg must be a user-type" msgid "__new__ arg must be a user-type"
msgstr "" msgstr ""
#: extmod/modubinascii.c extmod/moduhashlib.c py/objarray.c #: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c
msgid "a bytes-like object is required" msgid "a bytes-like object is required"
msgstr "" msgstr ""
@ -2477,6 +2469,10 @@ msgstr ""
msgid "asm overflow" msgid "asm overflow"
msgstr "" msgstr ""
#: py/compile.c
msgid "async for/with outside async function"
msgstr ""
#: extmod/ulab/code/numpy/numerical.c #: extmod/ulab/code/numpy/numerical.c
msgid "attempt to get (arg)min/(arg)max of empty sequence" msgid "attempt to get (arg)min/(arg)max of empty sequence"
msgstr "" msgstr ""
@ -2529,7 +2525,7 @@ msgstr ""
msgid "bitmap sizes must match" msgid "bitmap sizes must match"
msgstr "" msgstr ""
#: extmod/modurandom.c #: extmod/modrandom.c
msgid "bits must be 32 or less" msgid "bits must be 32 or less"
msgstr "" msgstr ""
@ -2610,11 +2606,11 @@ msgstr ""
msgid "can't assign to expression" msgid "can't assign to expression"
msgstr "" msgstr ""
#: extmod/moduasyncio.c #: extmod/modasyncio.c
msgid "can't cancel self" msgid "can't cancel self"
msgstr "" msgstr ""
#: py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c #: shared-module/adafruit_pixelbuf/PixelBuf.c
msgid "can't convert %q to %q" msgid "can't convert %q to %q"
msgstr "" msgstr ""
@ -2628,6 +2624,11 @@ msgstr ""
msgid "can't convert %s to float" msgid "can't convert %s to float"
msgstr "" msgstr ""
#: py/runtime.c
#, c-format
msgid "can't convert %s to int"
msgstr ""
#: py/objstr.c #: py/objstr.c
msgid "can't convert '%q' object to %q implicitly" msgid "can't convert '%q' object to %q implicitly"
msgstr "" msgstr ""
@ -2738,7 +2739,7 @@ msgstr ""
msgid "can't unambiguously get sizeof scalar" msgid "can't unambiguously get sizeof scalar"
msgstr "" msgstr ""
#: extmod/moduasyncio.c #: extmod/modasyncio.c
msgid "can't wait" msgid "can't wait"
msgstr "" msgstr ""
@ -2830,7 +2831,7 @@ msgstr ""
msgid "complex values not supported" msgid "complex values not supported"
msgstr "" msgstr ""
#: extmod/moduzlib.c #: extmod/modzlib.c
msgid "compression header" msgid "compression header"
msgstr "" msgstr ""
@ -2944,7 +2945,7 @@ msgstr ""
msgid "empty file" msgid "empty file"
msgstr "" msgstr ""
#: extmod/moduasyncio.c extmod/moduheapq.c #: extmod/modasyncio.c extmod/modheapq.c
msgid "empty heap" msgid "empty heap"
msgstr "" msgstr ""
@ -3073,6 +3074,10 @@ msgstr ""
msgid "font must be 2048 bytes long" msgid "font must be 2048 bytes long"
msgstr "" msgstr ""
#: extmod/moddeflate.c
msgid "format"
msgstr ""
#: py/objstr.c #: py/objstr.c
msgid "format requires a dict" msgid "format requires a dict"
msgstr "" msgstr ""
@ -3149,11 +3154,11 @@ msgstr ""
msgid "graphic must be 2048 bytes long" msgid "graphic must be 2048 bytes long"
msgstr "" msgstr ""
#: extmod/moduhashlib.c #: extmod/modhashlib.c
msgid "hash is final" msgid "hash is final"
msgstr "" msgstr ""
#: extmod/moduheapq.c #: extmod/modheapq.c
msgid "heap must be a list" msgid "heap must be a list"
msgstr "" msgstr ""
@ -3185,7 +3190,7 @@ msgstr ""
msgid "incomplete format key" msgid "incomplete format key"
msgstr "" msgstr ""
#: extmod/modubinascii.c #: extmod/modbinascii.c
msgid "incorrect padding" msgid "incorrect padding"
msgstr "" msgstr ""
@ -3314,7 +3319,7 @@ msgid "interval must be in range %s-%s"
msgstr "" msgstr ""
#: py/compile.c #: py/compile.c
msgid "invalid architecture" msgid "invalid arch"
msgstr "" msgstr ""
#: shared-bindings/bitmaptools/__init__.c #: shared-bindings/bitmaptools/__init__.c
@ -3503,6 +3508,10 @@ msgstr ""
msgid "memoryview: length is not a multiple of itemsize" msgid "memoryview: length is not a multiple of itemsize"
msgstr "" msgstr ""
#: extmod/modtime.c
msgid "mktime needs a tuple of length 8 or 9"
msgstr ""
#: extmod/ulab/code/numpy/linalg/linalg.c #: extmod/ulab/code/numpy/linalg/linalg.c
msgid "mode must be complete, or reduced" msgid "mode must be complete, or reduced"
msgstr "" msgstr ""
@ -3600,7 +3609,7 @@ msgstr ""
msgid "no default packer" msgid "no default packer"
msgstr "" msgstr ""
#: extmod/modurandom.c #: extmod/modrandom.c
msgid "no default seed" msgid "no default seed"
msgstr "" msgstr ""
@ -4027,7 +4036,7 @@ msgstr ""
msgid "source_bitmap must have value_count of 8" msgid "source_bitmap must have value_count of 8"
msgstr "" msgstr ""
#: extmod/modure.c #: extmod/modre.c
msgid "splitting with sub-captures" msgid "splitting with sub-captures"
msgstr "" msgstr ""
@ -4076,7 +4085,7 @@ msgstr ""
msgid "super() can't find self" msgid "super() can't find self"
msgstr "" msgstr ""
#: extmod/modujson.c #: extmod/modjson.c
msgid "syntax error in JSON" msgid "syntax error in JSON"
msgstr "" msgstr ""
@ -4084,7 +4093,7 @@ msgstr ""
msgid "syntax error in uctypes descriptor" msgid "syntax error in uctypes descriptor"
msgstr "" msgstr ""
#: extmod/utime_mphal.c #: extmod/modtime.c
msgid "ticks interval overflow" msgid "ticks interval overflow"
msgstr "" msgstr ""
@ -4262,7 +4271,7 @@ msgid "unsupported format character '%c' (0x%x) at index %d"
msgstr "" msgstr ""
#: py/runtime.c #: py/runtime.c
msgid "unsupported type for %q: '%q'" msgid "unsupported type for %q: '%s'"
msgstr "" msgstr ""
#: py/runtime.c #: py/runtime.c
@ -4290,6 +4299,10 @@ msgstr ""
msgid "value out of range of target" msgid "value out of range of target"
msgstr "" msgstr ""
#: extmod/moddeflate.c
msgid "wbits"
msgstr ""
#: shared-bindings/is31fl3741/FrameBuffer.c #: shared-bindings/is31fl3741/FrameBuffer.c
msgid "width must be greater than zero" msgid "width must be greater than zero"
msgstr "" msgstr ""

View File

@ -48,6 +48,14 @@ mp_uint_t mp_verbose_flag = 0;
// Make it larger on a 64 bit machine, because pointers are larger. // Make it larger on a 64 bit machine, because pointers are larger.
long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4); long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4);
STATIC void stdout_print_strn(void *env, const char *str, size_t len) {
(void)env;
ssize_t dummy = write(STDOUT_FILENO, str, len);
(void)dummy;
}
STATIC const mp_print_t mp_stdout_print = {NULL, stdout_print_strn};
STATIC void stderr_print_strn(void *env, const char *str, size_t len) { STATIC void stderr_print_strn(void *env, const char *str, size_t len) {
(void)env; (void)env;
ssize_t dummy = write(STDERR_FILENO, str, len); ssize_t dummy = write(STDERR_FILENO, str, len);
@ -59,7 +67,12 @@ STATIC const mp_print_t mp_stderr_print = {NULL, stderr_print_strn};
STATIC int compile_and_save(const char *file, const char *output_file, const char *source_file) { STATIC int compile_and_save(const char *file, const char *output_file, const char *source_file) {
nlr_buf_t nlr; nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) { if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_file(file); mp_lexer_t *lex;
if (strcmp(file, "-") == 0) {
lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, STDIN_FILENO, false);
} else {
lex = mp_lexer_new_from_file(file);
}
qstr source_name; qstr source_name;
if (source_file == NULL) { if (source_file == NULL) {
@ -77,17 +90,23 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
cm.context = m_new_obj(mp_module_context_t); cm.context = m_new_obj(mp_module_context_t);
mp_compile_to_raw_code(&parse_tree, source_name, false, &cm); mp_compile_to_raw_code(&parse_tree, source_name, false, &cm);
vstr_t vstr; if ((output_file != NULL && strcmp(output_file, "-") == 0) ||
vstr_init(&vstr, 16); (output_file == NULL && strcmp(file, "-") == 0)) {
if (output_file == NULL) { mp_raw_code_save(&cm, (mp_print_t *)&mp_stdout_print);
vstr_add_str(&vstr, file);
vstr_cut_tail_bytes(&vstr, 2);
vstr_add_str(&vstr, "mpy");
} else { } else {
vstr_add_str(&vstr, output_file); vstr_t vstr;
vstr_init(&vstr, 16);
if (output_file == NULL) {
vstr_add_str(&vstr, file);
vstr_cut_tail_bytes(&vstr, 2);
vstr_add_str(&vstr, "mpy");
} else {
vstr_add_str(&vstr, output_file);
}
mp_raw_code_save_file(&cm, vstr_null_terminated_str(&vstr));
vstr_clear(&vstr);
} }
mp_raw_code_save_file(&cm, vstr_null_terminated_str(&vstr));
vstr_clear(&vstr);
nlr_pop(); nlr_pop();
return 0; return 0;
@ -100,10 +119,10 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
STATIC int usage(char **argv) { STATIC int usage(char **argv) {
printf( printf(
"usage: %s [<opts>] [-X <implopt>] <input filename>\n" "usage: %s [<opts>] [-X <implopt>] [--] <input filename>\n"
"Options:\n" "Options:\n"
"--version : show version information\n" "--version : show version information\n"
"-o : output file for compiled bytecode (defaults to input with .mpy extension)\n" "-o : output file for compiled bytecode (defaults to input filename with .mpy extension, or stdout if input is stdin)\n"
"-s : source filename to embed in the compiled bytecode (defaults to input file)\n" "-s : source filename to embed in the compiled bytecode (defaults to input file)\n"
"-v : verbose (trace various operations); can be multiple\n" "-v : verbose (trace various operations); can be multiple\n"
"-O[N] : apply bytecode optimizations of level N\n" "-O[N] : apply bytecode optimizations of level N\n"
@ -220,10 +239,11 @@ MP_NOINLINE int main_(int argc, char **argv) {
const char *input_file = NULL; const char *input_file = NULL;
const char *output_file = NULL; const char *output_file = NULL;
const char *source_file = NULL; const char *source_file = NULL;
bool option_parsing_active = true;
// parse main options // parse main options
for (int a = 1; a < argc; a++) { for (int a = 1; a < argc; a++) {
if (argv[a][0] == '-') { if (option_parsing_active && argv[a][0] == '-' && argv[a][1] != '\0') {
if (strcmp(argv[a], "-X") == 0) { if (strcmp(argv[a], "-X") == 0) {
a += 1; a += 1;
} else if (strcmp(argv[a], "--version") == 0) { } else if (strcmp(argv[a], "--version") == 0) {
@ -309,6 +329,8 @@ MP_NOINLINE int main_(int argc, char **argv) {
} else { } else {
return usage(argv); return usage(argv);
} }
} else if (strcmp(argv[a], "--") == 0) {
option_parsing_active = false;
} else { } else {
return usage(argv); return usage(argv);
} }

View File

@ -95,7 +95,7 @@
// MINGW only handles these errno names. // MINGW only handles these errno names.
#ifdef __MINGW32__ #ifdef __MINGW32__
#define MICROPY_PY_UERRNO_LIST \ #define MICROPY_PY_ERRNO_LIST \
X(EPERM) \ X(EPERM) \
X(ENOENT) \ X(ENOENT) \
X(ESRCH) \ X(ESRCH) \

View File

@ -100,7 +100,7 @@ def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None,
if not src: if not src:
raise ValueError("src is required") raise ValueError("src is required")
if not os.path.exists(src): if not os.path.exists(src):
raise CrossCompileError("Input .py file not found: {}.".format(src_py)) raise CrossCompileError("Input .py file not found: {}.".format(src))
args = [] args = []

View File

@ -48,7 +48,7 @@
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
#define MICROPY_PY_COLLECTIONS_DEQUE (0) #define MICROPY_PY_COLLECTIONS_DEQUE (0)
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0)
#define MICROPY_PY_UERRNO_LIST \ #define MICROPY_PY_ERRNO_LIST \
X(EPERM) \ X(EPERM) \
X(ENOENT) \ X(ENOENT) \
X(EIO) \ X(EIO) \
@ -85,7 +85,7 @@
#define SPI_FLASH_MAX_BAUDRATE 24000000 #define SPI_FLASH_MAX_BAUDRATE 24000000
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1)
#define MICROPY_PY_FUNCTION_ATTRS (1) #define MICROPY_PY_FUNCTION_ATTRS (1)
// MICROPY_PY_UERRNO_LIST - Use the default // MICROPY_PY_ERRNO_LIST - Use the default
#endif // SAM_D5X_E5X #endif // SAM_D5X_E5X

View File

@ -178,7 +178,7 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart3);
CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart4);
/* Set UART_CLK_PODF. */ /* Set UART_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); CLOCK_SetDiv(kCLOCK_UartDiv, 1);
/* Set Uart clock source. */ /* Set Uart clock source. */
CLOCK_SetMux(kCLOCK_UartMux, 0); CLOCK_SetMux(kCLOCK_UartMux, 0);
/* Disable SPDIF clock gate. */ /* Disable SPDIF clock gate. */

View File

@ -213,7 +213,7 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart3);
CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart4);
/* Set UART_CLK_PODF. */ /* Set UART_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); CLOCK_SetDiv(kCLOCK_UartDiv, 1);
/* Set Uart clock source. */ /* Set Uart clock source. */
CLOCK_SetMux(kCLOCK_UartMux, 0); CLOCK_SetMux(kCLOCK_UartMux, 0);
/* Disable SPDIF clock gate. */ /* Disable SPDIF clock gate. */

View File

@ -246,7 +246,7 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart7);
CLOCK_DisableClock(kCLOCK_Lpuart8); CLOCK_DisableClock(kCLOCK_Lpuart8);
/* Set UART_CLK_PODF. */ /* Set UART_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); CLOCK_SetDiv(kCLOCK_UartDiv, 1);
/* Set Uart clock source. */ /* Set Uart clock source. */
CLOCK_SetMux(kCLOCK_UartMux, 0); CLOCK_SetMux(kCLOCK_UartMux, 0);
/* Disable SPDIF clock gate. */ /* Disable SPDIF clock gate. */

View File

@ -224,7 +224,7 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart7);
CLOCK_DisableClock(kCLOCK_Lpuart8); CLOCK_DisableClock(kCLOCK_Lpuart8);
/* Set UART_CLK_PODF. */ /* Set UART_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); CLOCK_SetDiv(kCLOCK_UartDiv, 1);
/* Set Uart clock source. */ /* Set Uart clock source. */
CLOCK_SetMux(kCLOCK_UartMux, 0); CLOCK_SetMux(kCLOCK_UartMux, 0);
/* Disable LCDIF clock gate. */ /* Disable LCDIF clock gate. */

View File

@ -231,7 +231,7 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart7);
CLOCK_DisableClock(kCLOCK_Lpuart8); CLOCK_DisableClock(kCLOCK_Lpuart8);
/* Set UART_CLK_PODF. */ /* Set UART_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); CLOCK_SetDiv(kCLOCK_UartDiv, 1);
/* Set Uart clock source. */ /* Set Uart clock source. */
CLOCK_SetMux(kCLOCK_UartMux, 0); CLOCK_SetMux(kCLOCK_UartMux, 0);
/* Disable LCDIF clock gate. */ /* Disable LCDIF clock gate. */

View File

@ -298,6 +298,7 @@ SRC_MBEDTLS := $(addprefix lib/mbedtls/library/, \
cipher.c \ cipher.c \
cipher_wrap.c \ cipher_wrap.c \
cmac.c \ cmac.c \
constant_time.c \
ctr_drbg.c \ ctr_drbg.c \
debug.c \ debug.c \
des.c \ des.c \
@ -316,7 +317,6 @@ SRC_MBEDTLS := $(addprefix lib/mbedtls/library/, \
md4.c \ md4.c \
md5.c \ md5.c \
md.c \ md.c \
md_wrap.c \
oid.c \ oid.c \
padlock.c \ padlock.c \
pem.c \ pem.c \
@ -340,6 +340,7 @@ SRC_MBEDTLS := $(addprefix lib/mbedtls/library/, \
ssl_ciphersuites.c \ ssl_ciphersuites.c \
ssl_cli.c \ ssl_cli.c \
ssl_cookie.c \ ssl_cookie.c \
ssl_msg.c \
ssl_srv.c \ ssl_srv.c \
ssl_ticket.c \ ssl_ticket.c \
ssl_tls.c \ ssl_tls.c \

View File

@ -59,8 +59,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
cyw43_pin_type, cyw43_pin_type,
MP_QSTR_CywPin, MP_QSTR_CywPin,
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
print, shared_bindings_microcontroller_pin_print, print, shared_bindings_microcontroller_pin_print
unary_op, mp_generic_unary_op
); );
//| PM_STANDARD: int //| PM_STANDARD: int

View File

@ -27,8 +27,8 @@ FROZEN_MANIFEST ?= variants/manifest.py
PROG ?= micropython PROG ?= micropython
# qstr definitions (must come before including py.mk) # qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h QSTR_DEFS += qstrdefsport.h
QSTR_GLOBAL_DEPENDENCIES = $(VARIANT_DIR)/mpconfigvariant.h QSTR_GLOBAL_DEPENDENCIES += $(VARIANT_DIR)/mpconfigvariant.h
# OS name, for simple autoconfig # OS name, for simple autoconfig
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
@ -59,8 +59,8 @@ endif
# Remove unused sections. # Remove unused sections.
COPT += -fdata-sections -ffunction-sections COPT += -fdata-sections -ffunction-sections
# Always enable symbols -- They're occasionally useful, and don't make it into the # Note: Symbols and debug information will still be stripped from the final binary
# final .bin/.hex/.dfu so the extra size doesn't matter. # unless "DEBUG=1" or "STRIP=" is passed to make, see README.md for details.
CFLAGS += -g CFLAGS += -g
ifndef DEBUG ifndef DEBUG
@ -138,7 +138,7 @@ CFLAGS += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0
LDFLAGS += $(LIBPTHREAD) LDFLAGS += $(LIBPTHREAD)
endif endif
ifeq ($(MICROPY_PY_USSL),1) ifeq ($(MICROPY_PY_SSL),1)
ifeq ($(MICROPY_SSL_AXTLS),1) ifeq ($(MICROPY_SSL_AXTLS),1)
endif endif
@ -200,8 +200,6 @@ SRC_C += \
unix_mphal.c \ unix_mphal.c \
mpthreadport.c \ mpthreadport.c \
input.c \ input.c \
modtime.c \
moduselect.c \
alloc.c \ alloc.c \
fatfs_port.c \ fatfs_port.c \
supervisor/stub/filesystem.c \ supervisor/stub/filesystem.c \
@ -211,6 +209,10 @@ SRC_C += \
$(SRC_MOD) \ $(SRC_MOD) \
$(wildcard $(VARIANT_DIR)/*.c) $(wildcard $(VARIANT_DIR)/*.c)
# CIRCUITPY-CHANGE
# CircuitPython doesn't use extmod/modtime.c, but ports/unix/extmod.c depends on it.
SRC_EXTMOD_C += extmod/modtime.c
$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h $(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h
SHARED_SRC_C += $(addprefix shared/,\ SHARED_SRC_C += $(addprefix shared/,\
@ -262,13 +264,13 @@ include $(TOP)/py/mkrules.mk
.PHONY: test test_full .PHONY: test test_full
# CIRCUITPY: these two targets are ours # CIRCUITPY-CHANGE: these two targets are for CircuitPython builds
.PHONY: print-failures clean-failures .PHONY: print-failures clean-failures
print-failures clean-failures: print-failures clean-failures:
../../tests/run-tests.py --$@ ../../tests/run-tests.py --$@
# CIRCUITPY: support for passing args to run-tests, like `make test TEST_ARGS="basics/*.py"` # CIRCUITPY-CHANGE: support for passing args to run-tests, like `make test TEST_ARGS="basics/*.py"`
TEST_ARGS ?= TEST_ARGS ?=
test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py
$(eval DIRNAME=ports/$(notdir $(CURDIR))) $(eval DIRNAME=ports/$(notdir $(CURDIR)))

View File

@ -40,8 +40,8 @@ or
>>> import mip >>> import mip
>>> mip.install("hmac") >>> mip.install("hmac")
Browse available modules at [micropython-lib] Browse available modules at
(https://github.com/micropython/micropython-lib). See [micropython-lib](https://github.com/micropython/micropython-lib). See
[Package management](https://docs.micropython.org/en/latest/reference/packages.html) [Package management](https://docs.micropython.org/en/latest/reference/packages.html)
for more information about `mip`. for more information about `mip`.
@ -70,5 +70,19 @@ or not). If you intend to build MicroPython with additional options
(like cross-compiling), the same set of options should be passed to `make (like cross-compiling), the same set of options should be passed to `make
deplibs`. To actually enable/disable use of dependencies, edit the deplibs`. To actually enable/disable use of dependencies, edit the
`ports/unix/mpconfigport.mk` file, which has inline descriptions of the `ports/unix/mpconfigport.mk` file, which has inline descriptions of the
options. For example, to build the SSL module, `MICROPY_PY_USSL` should be options. For example, to build the SSL module, `MICROPY_PY_SSL` should be
set to 1. set to 1.
Debug Symbols
-------------
By default, builds are stripped of symbols and debug information to save size.
To build a debuggable version of the Unix port, there are two options
1. Run `make [other arguments] DEBUG=1`. Note setting `DEBUG` also reduces the
optimisation level, so it's not a good option for builds that also want the
best performance.
2. Run `make [other arguments] STRIP=`. Note that the value of `STRIP` is
empty. This will skip the build step that strips symbols and debug
information, but changes nothing else in the build configuration.

View File

@ -48,7 +48,7 @@
#include "py/mphal.h" #include "py/mphal.h"
#include "py/mpthread.h" #include "py/mpthread.h"
#include "extmod/misc.h" #include "extmod/misc.h"
#include "extmod/moduplatform.h" #include "extmod/modplatform.h"
#include "extmod/vfs.h" #include "extmod/vfs.h"
#include "extmod/vfs_posix.h" #include "extmod/vfs_posix.h"
#include "genhdr/mpversion.h" #include "genhdr/mpversion.h"
@ -69,12 +69,20 @@ long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4);
#define MICROPY_GC_SPLIT_HEAP_N_HEAPS (1) #define MICROPY_GC_SPLIT_HEAP_N_HEAPS (1)
#endif #endif
#if !MICROPY_PY_SYS_PATH
#error "The unix port requires MICROPY_PY_SYS_PATH=1"
#endif
#if !MICROPY_PY_SYS_ARGV
#error "The unix port requires MICROPY_PY_SYS_ARGV=1"
#endif
STATIC void stderr_print_strn(void *env, const char *str, size_t len) { STATIC void stderr_print_strn(void *env, const char *str, size_t len) {
(void)env; (void)env;
ssize_t ret; ssize_t ret;
MP_HAL_RETRY_SYSCALL(ret, write(STDERR_FILENO, str, len), {}); MP_HAL_RETRY_SYSCALL(ret, write(STDERR_FILENO, str, len), {});
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
mp_uos_dupterm_tx_strn(str, len); mp_os_dupterm_tx_strn(str, len);
#endif #endif
} }
@ -540,44 +548,40 @@ MP_NOINLINE int main_(int argc, char **argv) {
} }
#endif #endif
char *home = getenv("HOME");
char *path = getenv("MICROPYPATH");
if (path == NULL) {
path = MICROPY_PY_SYS_PATH_DEFAULT;
}
size_t path_num = 1; // [0] is for current dir (or base dir of the script)
if (*path == PATHLIST_SEP_CHAR) {
path_num++;
}
for (char *p = path; p != NULL; p = strchr(p, PATHLIST_SEP_CHAR)) {
path_num++;
if (p != NULL) {
p++;
}
}
mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), path_num);
mp_obj_t *path_items;
mp_obj_list_get(mp_sys_path, &path_num, &path_items);
path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_);
{ {
char *p = path; // sys.path starts as [""]
for (mp_uint_t i = 1; i < path_num; i++) { mp_sys_path = mp_obj_new_list(0, NULL);
char *p1 = strchr(p, PATHLIST_SEP_CHAR); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_));
if (p1 == NULL) {
p1 = p + strlen(p); // Add colon-separated entries from MICROPYPATH.
char *home = getenv("HOME");
char *path = getenv("MICROPYPATH");
if (path == NULL) {
path = MICROPY_PY_SYS_PATH_DEFAULT;
}
if (*path == PATHLIST_SEP_CHAR) {
// First entry is empty. We've already added an empty entry to sys.path, so skip it.
++path;
}
bool path_remaining = *path;
while (path_remaining) {
char *path_entry_end = strchr(path, PATHLIST_SEP_CHAR);
if (path_entry_end == NULL) {
path_entry_end = path + strlen(path);
path_remaining = false;
} }
if (p[0] == '~' && p[1] == '/' && home != NULL) { if (path[0] == '~' && path[1] == '/' && home != NULL) {
// Expand standalone ~ to $HOME // Expand standalone ~ to $HOME
int home_l = strlen(home); int home_l = strlen(home);
vstr_t vstr; vstr_t vstr;
vstr_init(&vstr, home_l + (p1 - p - 1) + 1); vstr_init(&vstr, home_l + (path_entry_end - path - 1) + 1);
vstr_add_strn(&vstr, home, home_l); vstr_add_strn(&vstr, home, home_l);
vstr_add_strn(&vstr, p + 1, p1 - p - 1); vstr_add_strn(&vstr, path + 1, path_entry_end - path - 1);
path_items[i] = mp_obj_new_str_from_vstr(&vstr); mp_obj_list_append(mp_sys_path, mp_obj_new_str_from_vstr(&vstr));
} else { } else {
path_items[i] = mp_obj_new_str_via_qstr(p, p1 - p); mp_obj_list_append(mp_sys_path, mp_obj_new_str_via_qstr(path, path_entry_end - path));
} }
p = p1 + 1; path = path_entry_end + 1;
} }
} }
@ -666,7 +670,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
return handle_uncaught_exception(nlr.ret_val) & 0xff; return handle_uncaught_exception(nlr.ret_val) & 0xff;
} }
if (mp_obj_is_package(mod) && !subpkg_tried) { // If this module is a package, see if it has a `__main__.py`.
mp_obj_t dest[2];
mp_load_method_protected(mod, MP_QSTR___path__, dest, true);
if (dest[0] != MP_OBJ_NULL && !subpkg_tried) {
subpkg_tried = true; subpkg_tried = true;
vstr_t vstr; vstr_t vstr;
int len = strlen(argv[a + 1]); int len = strlen(argv[a + 1]);
@ -709,7 +716,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
// Set base dir of the script as first entry in sys.path. // Set base dir of the script as first entry in sys.path.
char *p = strrchr(basedir, '/'); char *p = strrchr(basedir, '/');
path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir); mp_obj_list_store(mp_sys_path, MP_OBJ_NEW_SMALL_INT(0), mp_obj_new_str_via_qstr(basedir, p - basedir));
free(pathbuf); free(pathbuf);
set_sys_argv(argv, argc, a); set_sys_argv(argv, argc, a);

View File

@ -27,7 +27,7 @@
#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H
// Set mbedtls configuration // Set mbedtls configuration
#define MBEDTLS_CIPHER_MODE_CTR // needed for MICROPY_PY_UCRYPTOLIB_CTR #define MBEDTLS_CIPHER_MODE_CTR // needed for MICROPY_PY_CRYPTOLIB_CTR
// Enable mbedtls modules // Enable mbedtls modules
#define MBEDTLS_HAVEGE_C #define MBEDTLS_HAVEGE_C

View File

@ -329,8 +329,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
unary_op, jobject_unary_op, unary_op, jobject_unary_op,
attr, jobject_attr, attr, jobject_attr,
subscr, jobject_subscr, subscr, jobject_subscr,
iter, subscr_getiter, iter, subscr_getiter
// .locals_dict = &jobject_locals_dict,
); );
STATIC mp_obj_t new_jobject(jobject jo) { STATIC mp_obj_t new_jobject(jobject jo) {
@ -574,9 +573,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
MP_QSTR_jmethod, MP_QSTR_jmethod,
MP_TYPE_FLAG_NONE, MP_TYPE_FLAG_NONE,
print, jmethod_print, print, jmethod_print,
call, jmethod_call, call, jmethod_call
// .attr = jobject_attr,
// .locals_dict = &jobject_locals_dict,
); );
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -615,26 +612,26 @@ STATIC void create_jvm(void) {
jclass Object_class = JJ(FindClass, "java/lang/Object"); jclass Object_class = JJ(FindClass, "java/lang/Object");
Object_toString_mid = JJ(GetMethodID, Object_class, "toString", Object_toString_mid = JJ(GetMethodID, Object_class, "toString",
MP_ERROR_TEXT("()Ljava/lang/String;")); MP_COMPRESSED_ROM_TEXT("()Ljava/lang/String;"));
Class_getName_mid = (*env)->GetMethodID(env, Class_class, "getName", Class_getName_mid = (*env)->GetMethodID(env, Class_class, "getName",
MP_ERROR_TEXT("()Ljava/lang/String;")); MP_COMPRESSED_ROM_TEXT("()Ljava/lang/String;"));
Class_getField_mid = (*env)->GetMethodID(env, Class_class, "getField", Class_getField_mid = (*env)->GetMethodID(env, Class_class, "getField",
MP_ERROR_TEXT("(Ljava/lang/String;)Ljava/lang/reflect/Field;")); MP_COMPRESSED_ROM_TEXT("(Ljava/lang/String;)Ljava/lang/reflect/Field;"));
Class_getMethods_mid = (*env)->GetMethodID(env, Class_class, "getMethods", Class_getMethods_mid = (*env)->GetMethodID(env, Class_class, "getMethods",
MP_ERROR_TEXT("()[Ljava/lang/reflect/Method;")); MP_COMPRESSED_ROM_TEXT("()[Ljava/lang/reflect/Method;"));
Class_getConstructors_mid = (*env)->GetMethodID(env, Class_class, "getConstructors", Class_getConstructors_mid = (*env)->GetMethodID(env, Class_class, "getConstructors",
MP_ERROR_TEXT("()[Ljava/lang/reflect/Constructor;")); MP_COMPRESSED_ROM_TEXT("()[Ljava/lang/reflect/Constructor;"));
Method_getName_mid = (*env)->GetMethodID(env, method_class, "getName", Method_getName_mid = (*env)->GetMethodID(env, method_class, "getName",
MP_ERROR_TEXT("()Ljava/lang/String;")); MP_COMPRESSED_ROM_TEXT("()Ljava/lang/String;"));
List_class = JJ(FindClass, "java/util/List"); List_class = JJ(FindClass, "java/util/List");
List_get_mid = JJ(GetMethodID, List_class, "get", List_get_mid = JJ(GetMethodID, List_class, "get",
MP_ERROR_TEXT("(I)Ljava/lang/Object;")); MP_COMPRESSED_ROM_TEXT("(I)Ljava/lang/Object;"));
List_set_mid = JJ(GetMethodID, List_class, "set", List_set_mid = JJ(GetMethodID, List_class, "set",
MP_ERROR_TEXT("(ILjava/lang/Object;)Ljava/lang/Object;")); MP_COMPRESSED_ROM_TEXT("(ILjava/lang/Object;)Ljava/lang/Object;"));
List_size_mid = JJ(GetMethodID, List_class, "size", List_size_mid = JJ(GetMethodID, List_class, "size",
MP_ERROR_TEXT("()I")); MP_COMPRESSED_ROM_TEXT("()I"));
IndexException_class = JJ(FindClass, "java/lang/IndexOutOfBoundsException"); IndexException_class = JJ(FindClass, "java/lang/IndexOutOfBoundsException");
} }

View File

@ -86,7 +86,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
#endif #endif
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_machine) },
{ MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
{ MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
@ -110,6 +110,6 @@ const mp_obj_module_t mp_module_machine = {
.globals = (mp_obj_dict_t *)&machine_module_globals, .globals = (mp_obj_dict_t *)&machine_module_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_umachine, mp_module_machine); MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_machine, mp_module_machine);
#endif // MICROPY_PY_MACHINE #endif // MICROPY_PY_MACHINE

View File

@ -40,7 +40,7 @@ os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t va
os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value);
#endif #endif
STATIC mp_obj_t mp_uos_getenv(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mp_os_getenv(size_t n_args, const mp_obj_t *args) {
mp_obj_t var_in = args[0]; mp_obj_t var_in = args[0];
#if defined(MICROPY_UNIX_COVERAGE) #if defined(MICROPY_UNIX_COVERAGE)
mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none); mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none);
@ -50,14 +50,18 @@ STATIC mp_obj_t mp_uos_getenv(size_t n_args, const mp_obj_t *args) {
#endif #endif
const char *s = getenv(mp_obj_str_get_str(var_in)); const char *s = getenv(mp_obj_str_get_str(var_in));
if (s == NULL) { if (s == NULL) {
return n_args > 1 ? args[1] : mp_const_none; if (n_args == 2) {
return args[1];
}
return mp_const_none;
} }
return mp_obj_new_str(s, strlen(s)); return mp_obj_new_str(s, strlen(s));
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_getenv_obj, 1, 2, mp_uos_getenv); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_os_getenv_obj, 1, 2, mp_os_getenv);
// CIRCUITPY-CHANGE: getenv differences
#if defined(MICROPY_UNIX_COVERAGE) #if defined(MICROPY_UNIX_COVERAGE)
STATIC mp_obj_t mp_uos_getenv_int(mp_obj_t var_in) { STATIC mp_obj_t mp_os_getenv_int(mp_obj_t var_in) {
mp_int_t value; mp_int_t value;
os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value);
if (result == 0) { if (result == 0) {
@ -65,9 +69,9 @@ STATIC mp_obj_t mp_uos_getenv_int(mp_obj_t var_in) {
} }
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_getenv_int_obj, mp_uos_getenv_int); MP_DEFINE_CONST_FUN_OBJ_1(mp_os_getenv_int_obj, mp_os_getenv_int);
STATIC mp_obj_t mp_uos_getenv_str(mp_obj_t var_in) { STATIC mp_obj_t mp_os_getenv_str(mp_obj_t var_in) {
char buf[4096]; char buf[4096];
os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf));
if (result == 0) { if (result == 0) {
@ -75,10 +79,10 @@ STATIC mp_obj_t mp_uos_getenv_str(mp_obj_t var_in) {
} }
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_getenv_str_obj, mp_uos_getenv_str); MP_DEFINE_CONST_FUN_OBJ_1(mp_os_getenv_str_obj, mp_os_getenv_str);
#endif #endif
STATIC mp_obj_t mp_uos_putenv(mp_obj_t key_in, mp_obj_t value_in) { STATIC mp_obj_t mp_os_putenv(mp_obj_t key_in, mp_obj_t value_in) {
const char *key = mp_obj_str_get_str(key_in); const char *key = mp_obj_str_get_str(key_in);
const char *value = mp_obj_str_get_str(value_in); const char *value = mp_obj_str_get_str(value_in);
int ret; int ret;
@ -94,9 +98,9 @@ STATIC mp_obj_t mp_uos_putenv(mp_obj_t key_in, mp_obj_t value_in) {
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_uos_putenv_obj, mp_uos_putenv); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_os_putenv_obj, mp_os_putenv);
STATIC mp_obj_t mp_uos_unsetenv(mp_obj_t key_in) { STATIC mp_obj_t mp_os_unsetenv(mp_obj_t key_in) {
const char *key = mp_obj_str_get_str(key_in); const char *key = mp_obj_str_get_str(key_in);
int ret; int ret;
@ -111,9 +115,9 @@ STATIC mp_obj_t mp_uos_unsetenv(mp_obj_t key_in) {
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_unsetenv_obj, mp_uos_unsetenv); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_os_unsetenv_obj, mp_os_unsetenv);
STATIC mp_obj_t mp_uos_system(mp_obj_t cmd_in) { STATIC mp_obj_t mp_os_system(mp_obj_t cmd_in) {
const char *cmd = mp_obj_str_get_str(cmd_in); const char *cmd = mp_obj_str_get_str(cmd_in);
MP_THREAD_GIL_EXIT(); MP_THREAD_GIL_EXIT();
@ -124,18 +128,18 @@ STATIC mp_obj_t mp_uos_system(mp_obj_t cmd_in) {
return MP_OBJ_NEW_SMALL_INT(r); return MP_OBJ_NEW_SMALL_INT(r);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_system_obj, mp_uos_system); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_os_system_obj, mp_os_system);
STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { STATIC mp_obj_t mp_os_urandom(mp_obj_t num) {
mp_int_t n = mp_obj_get_int(num); mp_int_t n = mp_obj_get_int(num);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, n); vstr_init_len(&vstr, n);
mp_hal_get_random(n, vstr.buf); mp_hal_get_random(n, vstr.buf);
return mp_obj_new_bytes_from_vstr(&vstr); return mp_obj_new_bytes_from_vstr(&vstr);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_os_urandom_obj, mp_os_urandom);
STATIC mp_obj_t mp_uos_errno(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mp_os_errno(size_t n_args, const mp_obj_t *args) {
if (n_args == 0) { if (n_args == 0) {
return MP_OBJ_NEW_SMALL_INT(errno); return MP_OBJ_NEW_SMALL_INT(errno);
} }
@ -143,4 +147,4 @@ STATIC mp_obj_t mp_uos_errno(size_t n_args, const mp_obj_t *args) {
errno = mp_obj_get_int(args[0]); errno = mp_obj_get_int(args[0]);
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_errno_obj, 0, 1, mp_uos_errno); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_os_errno_obj, 0, 1, mp_os_errno);

View File

@ -4,7 +4,7 @@
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2014-2017 Paul Sokolovsky * Copyright (c) 2014-2017 Paul Sokolovsky
* Copyright (c) 2014-2017 Damien P. George * Copyright (c) 2014-2023 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -25,9 +25,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "py/mpconfig.h"
#if MICROPY_PY_UTIME
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
@ -35,10 +32,8 @@
#include <sys/time.h> #include <sys/time.h>
#include <math.h> #include <math.h>
#include "py/runtime.h"
#include "py/smallint.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "extmod/utime_mphal.h" #include "py/runtime.h"
#ifdef _WIN32 #ifdef _WIN32
static inline int msec_sleep_tv(struct timeval *tv) { static inline int msec_sleep_tv(struct timeval *tv) {
@ -66,7 +61,7 @@ static inline int msec_sleep_tv(struct timeval *tv) {
#error Unsupported clock() implementation #error Unsupported clock() implementation
#endif #endif
STATIC mp_obj_t mod_time_time(void) { STATIC mp_obj_t mp_time_time_get(void) {
#if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
@ -76,7 +71,6 @@ STATIC mp_obj_t mod_time_time(void) {
return mp_obj_new_int((mp_int_t)time(NULL)); return mp_obj_new_int((mp_int_t)time(NULL));
#endif #endif
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_time_obj, mod_time_time);
// Note: this is deprecated since CPy3.3, but pystone still uses it. // Note: this is deprecated since CPy3.3, but pystone still uses it.
STATIC mp_obj_t mod_time_clock(void) { STATIC mp_obj_t mod_time_clock(void) {
@ -91,7 +85,7 @@ STATIC mp_obj_t mod_time_clock(void) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_clock_obj, mod_time_clock); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_clock_obj, mod_time_clock);
STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) { STATIC mp_obj_t mp_time_sleep(mp_obj_t arg) {
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
struct timeval tv; struct timeval tv;
mp_float_t val = mp_obj_get_float(arg); mp_float_t val = mp_obj_get_float(arg);
@ -130,7 +124,6 @@ STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) {
#endif #endif
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_obj, mod_time_sleep);
STATIC mp_obj_t mod_time_gm_local_time(size_t n_args, const mp_obj_t *args, struct tm *(*time_func)(const time_t *timep)) { STATIC mp_obj_t mod_time_gm_local_time(size_t n_args, const mp_obj_t *args, struct tm *(*time_func)(const time_t *timep)) {
time_t t; time_t t;
@ -207,31 +200,8 @@ STATIC mp_obj_t mod_time_mktime(mp_obj_t tuple) {
} }
MP_DEFINE_CONST_FUN_OBJ_1(mod_time_mktime_obj, mod_time_mktime); MP_DEFINE_CONST_FUN_OBJ_1(mod_time_mktime_obj, mod_time_mktime);
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = { #define MICROPY_PY_TIME_EXTRA_GLOBALS \
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) }, { MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&mod_time_clock_obj) }, \
{ MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&mod_time_clock_obj) }, { MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&mod_time_gmtime_obj) }, \
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mod_time_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mod_time_localtime_obj) }, \
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mod_time_time_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
{ MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&mod_time_gmtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mod_time_localtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) }, { MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
const mp_obj_module_t mp_module_time = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_time_globals,
};
MP_REGISTER_MODULE(MP_QSTR_time, mp_module_time);
#endif // MICROPY_PY_UTIME

View File

@ -1,356 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Damien P. George
* Copyright (c) 2015-2017 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h"
#if MICROPY_PY_USELECT_POSIX
#if MICROPY_PY_USELECT
#error "Can't have both MICROPY_PY_USELECT and MICROPY_PY_USELECT_POSIX."
#endif
#include <stdio.h>
#include <errno.h>
#include <poll.h>
#include "py/runtime.h"
#include "py/stream.h"
#include "py/obj.h"
#include "py/objlist.h"
#include "py/objtuple.h"
#include "py/mphal.h"
#include "py/mpthread.h"
#define DEBUG 0
#if MICROPY_PY_SOCKET
extern const mp_obj_type_t mp_type_socket;
#endif
// Flags for poll()
#define FLAG_ONESHOT (1)
/// \class Poll - poll class
typedef struct _mp_obj_poll_t {
mp_obj_base_t base;
unsigned short alloc;
unsigned short len;
struct pollfd *entries;
mp_obj_t *obj_map;
short iter_cnt;
short iter_idx;
int flags;
// callee-owned tuple
mp_obj_t ret_tuple;
} mp_obj_poll_t;
STATIC int get_fd(mp_obj_t fdlike) {
if (mp_obj_is_obj(fdlike)) {
const mp_stream_p_t *stream_p = mp_get_stream_raise(fdlike, MP_STREAM_OP_IOCTL);
int err;
mp_uint_t res = stream_p->ioctl(fdlike, MP_STREAM_GET_FILENO, 0, &err);
if (res != MP_STREAM_ERROR) {
return res;
}
}
return mp_obj_get_int(fdlike);
}
/// \method register(obj[, eventmask])
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
bool is_fd = mp_obj_is_int(args[1]);
int fd = get_fd(args[1]);
mp_uint_t flags;
if (n_args == 3) {
flags = mp_obj_get_int(args[2]);
} else {
flags = POLLIN | POLLOUT;
}
struct pollfd *free_slot = NULL;
struct pollfd *entry = self->entries;
for (int i = 0; i < self->len; i++, entry++) {
int entry_fd = entry->fd;
if (entry_fd == fd) {
entry->events = flags;
return mp_const_false;
}
if (entry_fd == -1) {
free_slot = entry;
}
}
if (free_slot == NULL) {
if (self->len >= self->alloc) {
self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4);
if (self->obj_map) {
self->obj_map = m_renew(mp_obj_t, self->obj_map, self->alloc, self->alloc + 4);
}
self->alloc += 4;
}
free_slot = &self->entries[self->len++];
}
if (!is_fd) {
if (self->obj_map == NULL) {
self->obj_map = m_new0(mp_obj_t, self->alloc);
}
self->obj_map[free_slot - self->entries] = args[1];
}
free_slot->fd = fd;
free_slot->events = flags;
free_slot->revents = 0;
return mp_const_true;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register);
/// \method unregister(obj)
STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
struct pollfd *entries = self->entries;
int fd = get_fd(obj_in);
for (int i = self->len - 1; i >= 0; i--) {
if (entries->fd == fd) {
entries->fd = -1;
if (self->obj_map) {
self->obj_map[entries - self->entries] = MP_OBJ_NULL;
}
break;
}
entries++;
}
// TODO raise KeyError if obj didn't exist in map
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister);
/// \method modify(obj, eventmask)
STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
struct pollfd *entries = self->entries;
int fd = get_fd(obj_in);
for (int i = self->len - 1; i >= 0; i--) {
if (entries->fd == fd) {
entries->events = mp_obj_get_int(eventmask_in);
return mp_const_none;
}
entries++;
}
// obj doesn't exist in poller
mp_raise_OSError(MP_ENOENT);
}
MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify);
STATIC int poll_poll_internal(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
// work out timeout (it's given already in ms)
int timeout = -1;
int flags = 0;
if (n_args >= 2) {
if (args[1] != mp_const_none) {
mp_int_t timeout_i = mp_obj_get_int(args[1]);
if (timeout_i >= 0) {
timeout = timeout_i;
}
}
if (n_args >= 3) {
flags = mp_obj_get_int(args[2]);
}
}
self->flags = flags;
int n_ready;
MP_HAL_RETRY_SYSCALL(n_ready, poll(self->entries, self->len, timeout), mp_raise_OSError(err));
return n_ready;
}
/// \method poll([timeout])
/// Timeout is in milliseconds.
STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
int n_ready = poll_poll_internal(n_args, args);
if (n_ready == 0) {
return mp_const_empty_tuple;
}
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL));
int ret_i = 0;
struct pollfd *entries = self->entries;
for (int i = 0; i < self->len; i++, entries++) {
if (entries->revents != 0) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
// If there's an object stored, return it, otherwise raw fd
if (self->obj_map && self->obj_map[i] != MP_OBJ_NULL) {
t->items[0] = self->obj_map[i];
} else {
t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd);
}
t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents);
ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t);
if (self->flags & FLAG_ONESHOT) {
entries->events = 0;
}
}
}
return MP_OBJ_FROM_PTR(ret_list);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll);
STATIC mp_obj_t poll_ipoll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
if (self->ret_tuple == MP_OBJ_NULL) {
self->ret_tuple = mp_obj_new_tuple(2, NULL);
}
int n_ready = poll_poll_internal(n_args, args);
self->iter_cnt = n_ready;
self->iter_idx = 0;
return args[0];
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_ipoll_obj, 1, 3, poll_ipoll);
STATIC mp_obj_t poll_iternext(mp_obj_t self_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
if (self->iter_cnt == 0) {
return MP_OBJ_STOP_ITERATION;
}
self->iter_cnt--;
struct pollfd *entries = self->entries + self->iter_idx;
for (int i = self->iter_idx; i < self->len; i++, entries++) {
self->iter_idx++;
if (entries->revents != 0) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple);
// If there's an object stored, return it, otherwise raw fd
if (self->obj_map && self->obj_map[i] != MP_OBJ_NULL) {
t->items[0] = self->obj_map[i];
} else {
t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd);
}
t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents);
if (self->flags & FLAG_ONESHOT) {
entries->events = 0;
}
return MP_OBJ_FROM_PTR(t);
}
}
assert(!"inconsistent number of poll active entries");
self->iter_cnt = 0;
return MP_OBJ_STOP_ITERATION;
}
#if DEBUG
STATIC mp_obj_t poll_dump(mp_obj_t self_in) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
struct pollfd *entries = self->entries;
for (int i = self->len - 1; i >= 0; i--) {
printf("fd: %d ev: %x rev: %x", entries->fd, entries->events, entries->revents);
if (self->obj_map) {
printf(" obj: %p", self->obj_map[entries - self->entries]);
}
printf("\n");
entries++;
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(poll_dump_obj, poll_dump);
#endif
STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) },
{ MP_ROM_QSTR(MP_QSTR_unregister), MP_ROM_PTR(&poll_unregister_obj) },
{ MP_ROM_QSTR(MP_QSTR_modify), MP_ROM_PTR(&poll_modify_obj) },
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&poll_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipoll), MP_ROM_PTR(&poll_ipoll_obj) },
#if DEBUG
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&poll_dump_obj) },
#endif
};
STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_poll,
MP_QSTR_poll,
MP_TYPE_FLAG_ITER_IS_ITERNEXT,
iter, poll_iternext,
locals_dict, &poll_locals_dict
);
STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) {
int alloc = 4;
if (n_args > 0) {
alloc = mp_obj_get_int(args[0]);
}
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
poll->entries = m_new(struct pollfd, alloc);
poll->alloc = alloc;
poll->len = 0;
poll->obj_map = NULL;
poll->iter_cnt = 0;
poll->ret_tuple = MP_OBJ_NULL;
return MP_OBJ_FROM_PTR(poll);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_poll_obj, 0, 1, select_poll);
STATIC const mp_rom_map_elem_t mp_module_select_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uselect) },
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mp_select_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_POLLIN), MP_ROM_INT(POLLIN) },
{ MP_ROM_QSTR(MP_QSTR_POLLOUT), MP_ROM_INT(POLLOUT) },
{ MP_ROM_QSTR(MP_QSTR_POLLERR), MP_ROM_INT(POLLERR) },
{ MP_ROM_QSTR(MP_QSTR_POLLHUP), MP_ROM_INT(POLLHUP) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_select_globals, mp_module_select_globals_table);
const mp_obj_module_t mp_module_uselect = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
};
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect);
#endif // MICROPY_PY_USELECT_POSIX

View File

@ -37,7 +37,7 @@
// Variant-specific definitions. // Variant-specific definitions.
#include "mpconfigvariant.h" #include "mpconfigvariant.h"
// CIRCUITPY // CIRCUITPY-CHANGE
#define CIRCUITPY_MICROPYTHON_ADVANCED (1) #define CIRCUITPY_MICROPYTHON_ADVANCED (1)
#define MICROPY_PY_ASYNC_AWAIT (1) #define MICROPY_PY_ASYNC_AWAIT (1)
@ -140,12 +140,6 @@ typedef long mp_off_t;
#define MICROPY_STACKLESS_STRICT (0) #define MICROPY_STACKLESS_STRICT (0)
#endif #endif
// If settrace is enabled then we need code saving.
#if MICROPY_PY_SYS_SETTRACE
#define MICROPY_PERSISTENT_CODE_SAVE (1)
#define MICROPY_COMP_CONST (0)
#endif
// Unix-specific configuration of machine.mem*. // Unix-specific configuration of machine.mem*.
#define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr #define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr
#define MICROPY_MACHINE_MEM_GET_WRITE_ADDR mod_machine_mem_get_addr #define MICROPY_MACHINE_MEM_GET_WRITE_ADDR mod_machine_mem_get_addr
@ -162,13 +156,13 @@ typedef long mp_off_t;
// Ensure builtinimport.c works with -m. // Ensure builtinimport.c works with -m.
#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) #define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1)
// Don't default sys.argv because we do that in main. // Don't default sys.argv and sys.path because we do that in main.
#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) #define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0)
// Enable sys.executable. // Enable sys.executable.
#define MICROPY_PY_SYS_EXECUTABLE (1) #define MICROPY_PY_SYS_EXECUTABLE (1)
#define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) #define MICROPY_PY_SOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128)
// Bare-metal ports don't have stderr. Printing debug to stderr may give tests // Bare-metal ports don't have stderr. Printing debug to stderr may give tests
// which check stdout a chance to pass, etc. // which check stdout a chance to pass, etc.
@ -189,10 +183,10 @@ void mp_unix_mark_exec(void);
#endif #endif
// If enabled, configure how to seed random on init. // If enabled, configure how to seed random on init.
#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC #ifdef MICROPY_PY_RANDOM_SEED_INIT_FUNC
#include <stddef.h> #include <stddef.h>
void mp_hal_get_random(size_t n, void *buf); void mp_hal_get_random(size_t n, void *buf);
static inline unsigned long mp_urandom_seed_init(void) { static inline unsigned long mp_random_seed_init(void) {
unsigned long r; unsigned long r;
mp_hal_get_random(sizeof(r), &r); mp_hal_get_random(sizeof(r), &r);
return r; return r;
@ -260,4 +254,5 @@ static inline unsigned long mp_urandom_seed_init(void) {
#define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE) #define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE)
#endif #endif
#define RUN_BACKGROUND_TASKS ((void)0) // CIRCUITPY // CIRCUITPY-CHANGE
#define RUN_BACKGROUND_TASKS ((void)0)

View File

@ -8,8 +8,8 @@ MICROPY_FORCE_32BIT = 0
# 1 - use MicroPython version of readline # 1 - use MicroPython version of readline
MICROPY_USE_READLINE = 1 MICROPY_USE_READLINE = 1
# CIRCUITPY-CHANGE: not present
# btree module using Berkeley DB 1.xx # btree module using Berkeley DB 1.xx
# CIRCUITPY: not present
MICROPY_PY_BTREE = 0 MICROPY_PY_BTREE = 0
# _thread module using pthreads # _thread module using pthreads
@ -18,19 +18,22 @@ MICROPY_PY_THREAD = 1
# Subset of CPython termios module # Subset of CPython termios module
MICROPY_PY_TERMIOS = 1 MICROPY_PY_TERMIOS = 1
# CIRCUITPY-CHANGE: not present
# Subset of CPython socket module # Subset of CPython socket module
MICROPY_PY_SOCKET = 0 MICROPY_PY_SOCKET = 0
# ffi module requires libffi (libffi-dev Debian package) # ffi module requires libffi (libffi-dev Debian package)
MICROPY_PY_FFI = 1 MICROPY_PY_FFI = 1
# ussl module requires one of the TLS libraries below # CIRCUITPY-CHANGE: not present
MICROPY_PY_USSL = 0 # ssl module requires one of the TLS libraries below
MICROPY_PY_SSL = 0
# axTLS has minimal size but implements only a subset of modern TLS # axTLS has minimal size but implements only a subset of modern TLS
# functionality, so may have problems with some servers. # functionality, so may have problems with some servers.
MICROPY_SSL_AXTLS = 0 MICROPY_SSL_AXTLS = 0
# mbedTLS is more up to date and complete implementation, but also # mbedTLS is more up to date and complete implementation, but also
# more bloated. # more bloated.
# CIRCUITPY-CHANGE: not present
MICROPY_SSL_MBEDTLS = 0 MICROPY_SSL_MBEDTLS = 0
# jni module requires JVM/JNI # jni module requires JVM/JNI
@ -40,15 +43,15 @@ MICROPY_PY_JNI = 0
# as submodules (currently affects only libffi). # as submodules (currently affects only libffi).
MICROPY_STANDALONE = 0 MICROPY_STANDALONE = 0
# CIRCUITPY: not used # CIRCUITPY-CHANGE: not used
MICROPY_ROM_TEXT_COMPRESSION = 0 MICROPY_ROM_TEXT_COMPRESSION = 0
MICROPY_VFS_FAT = 1 MICROPY_VFS_FAT = 1
# CIRCUITPY: not used # CIRCUITPY-CHANGE: not used
MICROPY_VFS_LFS1 = 0 MICROPY_VFS_LFS1 = 0
MICROPY_VFS_LFS2 = 0 MICROPY_VFS_LFS2 = 0
# CIRCUITPY # CIRCUITPY-CHANGE
CIRCUITPY_ULAB = 1 CIRCUITPY_ULAB = 1
CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 1 CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 1
MICROPY_EMIT_NATIVE = 0 MICROPY_EMIT_NATIVE = 0

View File

@ -31,7 +31,8 @@
#define CHAR_CTRL_C (3) #define CHAR_CTRL_C (3)
#endif #endif
void mp_hal_set_interrupt_char(char c); // CIRCUITPY-CHANGE: mp_hal_set_interrupt_char(int) instead of char
void mp_hal_set_interrupt_char(int c);
bool mp_hal_is_interrupted(void); bool mp_hal_is_interrupted(void);
#define mp_hal_stdio_poll unused // this is not implemented, nor needed #define mp_hal_stdio_poll unused // this is not implemented, nor needed

View File

@ -191,6 +191,10 @@ void mp_thread_set_state(mp_state_thread_t *state) {
pthread_setspecific(tls_key, state); pthread_setspecific(tls_key, state);
} }
mp_uint_t mp_thread_get_id(void) {
return (mp_uint_t)pthread_self();
}
void mp_thread_start(void) { void mp_thread_start(void) {
// enable realtime priority if `-X realtime` command line parameter was set // enable realtime priority if `-X realtime` command line parameter was set
#if defined(__APPLE__) #if defined(__APPLE__)
@ -210,7 +214,7 @@ void mp_thread_start(void) {
mp_thread_unix_end_atomic_section(); mp_thread_unix_end_atomic_section();
} }
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
// default stack size is 8k machine-words // default stack size is 8k machine-words
if (*stack_size == 0) { if (*stack_size == 0) {
*stack_size = 8192 * sizeof(void *); *stack_size = 8192 * sizeof(void *);
@ -265,7 +269,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
mp_thread_unix_end_atomic_section(); mp_thread_unix_end_atomic_section();
return; MP_STATIC_ASSERT(sizeof(mp_uint_t) >= sizeof(pthread_t));
return (mp_uint_t)id;
er: er:
mp_raise_OSError(ret); mp_raise_OSError(ret);

View File

@ -72,7 +72,8 @@ STATIC void sighandler(int signum) {
} }
#endif #endif
void mp_hal_set_interrupt_char(char c) { // CIRCUITPY-CHANGE: mp_hal_set_interrupt_char(int) instead of char
void mp_hal_set_interrupt_char(int c) {
// configure terminal settings to (not) let ctrl-C through // configure terminal settings to (not) let ctrl-C through
if (c == CHAR_CTRL_C) { if (c == CHAR_CTRL_C) {
#ifndef _WIN32 #ifndef _WIN32
@ -95,7 +96,7 @@ void mp_hal_set_interrupt_char(char c) {
} }
} }
// CIRCUITPY // CIRCUITPY-CHANGE
bool mp_hal_is_interrupted(void) { bool mp_hal_is_interrupted(void) {
return false; return false;
} }
@ -192,8 +193,9 @@ main_term:;
void mp_hal_stdout_tx_strn(const char *str, size_t len) { void mp_hal_stdout_tx_strn(const char *str, size_t len) {
ssize_t ret; ssize_t ret;
MP_HAL_RETRY_SYSCALL(ret, write(STDOUT_FILENO, str, len), {}); MP_HAL_RETRY_SYSCALL(ret, write(STDOUT_FILENO, str, len), {});
// CIRCUITPY-CHANGE: need to conditionalize MICROPY_PY_OS_DUPTERM
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
mp_uos_dupterm_tx_strn(str, len); mp_os_dupterm_tx_strn(str, len);
#endif #endif
} }
@ -262,7 +264,7 @@ void mp_hal_get_random(size_t n, void *buf) {
#ifdef _HAVE_GETRANDOM #ifdef _HAVE_GETRANDOM
RAISE_ERRNO(getrandom(buf, n, 0), errno); RAISE_ERRNO(getrandom(buf, n, 0), errno);
#else #else
int fd = open("/dev/urandom", O_RDONLY); int fd = open("/dev/random", O_RDONLY);
RAISE_ERRNO(fd, errno); RAISE_ERRNO(fd, errno);
RAISE_ERRNO(read(fd, buf, n), errno); RAISE_ERRNO(read(fd, buf, n), errno);
close(fd); close(fd);

View File

@ -33,13 +33,16 @@
// Enable extra Unix features. // Enable extra Unix features.
#include "../mpconfigvariant_common.h" #include "../mpconfigvariant_common.h"
// Enable testing of split heap.
#define MICROPY_GC_SPLIT_HEAP (1)
#define MICROPY_GC_SPLIT_HEAP_N_HEAPS (4)
// Enable additional features. // Enable additional features.
#define MICROPY_DEBUG_PARSE_RULE_NAME (1) #define MICROPY_DEBUG_PARSE_RULE_NAME (1)
#define MICROPY_TRACKED_ALLOC (1) #define MICROPY_TRACKED_ALLOC (1)
#define MICROPY_WARNINGS_CATEGORY (1) #define MICROPY_WARNINGS_CATEGORY (1)
// Disable things never used in circuitpython // CIRCUITPY-CHANGE: Disable things never used in circuitpython
#define MICROPY_PY_UCRYPTOLIB (0) #define MICROPY_PY_CRYPTOLIB (0)
#define MICROPY_PY_UCRYPTOLIB_CTR (0) #define MICROPY_PY_CRYPTOLIB_CTR (0)
#define MICROPY_PY_STRUCT (0) // uses shared-bindings struct #define MICROPY_PY_STRUCT (0) // uses shared-bindings struct
#define MICROPY_GC_SPLIT_HEAP (0)

View File

@ -63,7 +63,7 @@
// Enable just the sys and os built-in modules. // Enable just the sys and os built-in modules.
#define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS (1)
#define MICROPY_PY_UOS (1) #define MICROPY_PY_OS (1)
// The minimum sets this to 1 to save flash. // The minimum sets this to 1 to save flash.
#define MICROPY_QSTR_BYTES_IN_HASH (2) #define MICROPY_QSTR_BYTES_IN_HASH (2)

View File

@ -7,7 +7,7 @@ MICROPY_PY_FFI = 0
MICROPY_PY_SOCKET = 0 MICROPY_PY_SOCKET = 0
MICROPY_PY_THREAD = 0 MICROPY_PY_THREAD = 0
MICROPY_PY_TERMIOS = 0 MICROPY_PY_TERMIOS = 0
MICROPY_PY_USSL = 0 MICROPY_PY_SSL = 0
MICROPY_USE_READLINE = 0 MICROPY_USE_READLINE = 0
MICROPY_VFS_FAT = 0 MICROPY_VFS_FAT = 0

View File

@ -58,7 +58,7 @@
#endif #endif
// Seed random on import. // Seed random on import.
#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) #define MICROPY_PY_RANDOM_SEED_INIT_FUNC (mp_random_seed_init())
// Allow exception details in low-memory conditions. // Allow exception details in low-memory conditions.
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
@ -87,37 +87,31 @@
#define MICROPY_PY_SYS_EXC_INFO (1) #define MICROPY_PY_SYS_EXC_INFO (1)
// Configure the "os" module with extra unix features. // Configure the "os" module with extra unix features.
#define MICROPY_PY_UOS_INCLUDEFILE "ports/unix/moduos.c" #define MICROPY_PY_OS_INCLUDEFILE "ports/unix/modos.c"
#define MICROPY_PY_UOS_ERRNO (1) #define MICROPY_PY_OS_ERRNO (1)
#define MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV (1) #define MICROPY_PY_OS_GETENV_PUTENV_UNSETENV (1)
#define MICROPY_PY_UOS_SEP (1) #define MICROPY_PY_OS_SEP (1)
#define MICROPY_PY_UOS_SYSTEM (1) #define MICROPY_PY_OS_SYSTEM (1)
#define MICROPY_PY_UOS_URANDOM (1) #define MICROPY_PY_OS_URANDOM (1)
// Enable the unix-specific "time" module. // Enable the unix-specific "time" module.
#define MICROPY_PY_UTIME (1) #define MICROPY_PY_TIME (1)
#define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_TIME_TIME_TIME_NS (1)
#define MICROPY_PY_TIME_CUSTOM_SLEEP (1)
#define MICROPY_PY_TIME_INCLUDEFILE "ports/unix/modtime.c"
// Enable the utimeq module used by the previous (v2) version of uasyncio. #if MICROPY_PY_SSL
#define MICROPY_PY_UTIMEQ (1) #define MICROPY_PY_HASHLIB_MD5 (1)
#define MICROPY_PY_HASHLIB_SHA1 (1)
#if MICROPY_PY_USSL #define MICROPY_PY_CRYPTOLIB (1)
#define MICROPY_PY_UHASHLIB_MD5 (1)
#define MICROPY_PY_UHASHLIB_SHA1 (1)
#define MICROPY_PY_UCRYPTOLIB (1)
#endif #endif
// Use the posix implementation of the "select" module (unless the variant // The "select" module is enabled by default, but disable select.select().
// specifically asks for the MicroPython version). #define MICROPY_PY_SELECT_POSIX_OPTIMISATIONS (1)
#ifndef MICROPY_PY_USELECT #define MICROPY_PY_SELECT_SELECT (0)
#define MICROPY_PY_USELECT (0)
#endif
#ifndef MICROPY_PY_USELECT_POSIX
#define MICROPY_PY_USELECT_POSIX (!MICROPY_PY_USELECT)
#endif
// Enable the "websocket" module. // Enable the "websocket" module.
#define MICROPY_PY_UWEBSOCKET (1) #define MICROPY_PY_WEBSOCKET (1)
// Enable the "machine" module, mostly for machine.mem*. // Enable the "machine" module, mostly for machine.mem*.
#define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE (1)

View File

@ -290,7 +290,7 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) {
#define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff)) #define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff))
// all these bit arithmetics need coverage testing! // all these bit-arithmetic operations need coverage testing!
#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f)) #define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f))
#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff)) #define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff))

View File

@ -3,7 +3,7 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George * Copyright (c) 2014 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal

View File

@ -215,7 +215,7 @@ long long mp_binary_get_int(size_t size, bool is_signed, bool big_endian, const
val = -1; val = -1;
} }
for (uint i = 0; i < size; i++) { for (uint i = 0; i < size; i++) {
// CIRCUITPY fix for undefined behavior on left shift // CIRCUITPY-CHANGE: fix for undefined behavior on left shift
val *= 256; val *= 256;
val |= *src; val |= *src;
src += delta; src += delta;

View File

@ -133,7 +133,7 @@ extern const mp_obj_module_t mp_module_builtins;
extern const mp_obj_module_t mp_module_sys; extern const mp_obj_module_t mp_module_sys;
// Modules needed by the parser when MICROPY_COMP_MODULE_CONST is enabled. // Modules needed by the parser when MICROPY_COMP_MODULE_CONST is enabled.
extern const mp_obj_module_t mp_module_uerrno; extern const mp_obj_module_t mp_module_errno;
extern const mp_obj_module_t mp_module_uctypes; extern const mp_obj_module_t mp_module_uctypes;
extern const mp_obj_module_t mp_module_machine; extern const mp_obj_module_t mp_module_machine;

Some files were not shown because too many files have changed in this diff Show More