This is an automated email from the ASF dual-hosted git repository. hsun pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
commit c7ebd6f5c2382a94e5d52f0cd7860926a5e82df7 Author: sunhe05 <[email protected]> AuthorDate: Sun Apr 23 09:26:53 2023 +0000 Remove mesapy from the submodule Mesapy contains files that voilate apache open-source policy. --- .gitmodules | 4 - CMakeLists.txt | 30 +- cmake/TeaclaveUtils.cmake | 3 +- services/access_control/python/acs_py_enclave.c | 3191 +++++++++++++++++++++++ third_party/mesapy | 1 - 5 files changed, 3194 insertions(+), 35 deletions(-) diff --git a/.gitmodules b/.gitmodules index bcd934bd..54ac1e5e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,6 @@ [submodule "third_party/rust-sgx-sdk"] path = third_party/rust-sgx-sdk url = https://github.com/apache/incubator-teaclave-sgx-sdk.git -[submodule "third_party/mesapy"] - path = third_party/mesapy - url = https://github.com/mesalock-linux/mesapy.git - branch = sgx [submodule "third_party/wasm-micro-runtime"] path = third_party/wasm-micro-runtime url = https://github.com/bytecodealliance/wasm-micro-runtime diff --git a/CMakeLists.txt b/CMakeLists.txt index 59b01f52..64413f3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,6 @@ option(TEST_MODE "Turn on/off test mode" OFF) option(SGX_SIM_MODE "Turn on/off sgx simulation mode" OFF) option(DCAP "Turn on/off DCAP attestation" OFF) option(GIT_SUBMODULE "Check submodules during build" ON) -option(USE_PREBUILT_MESAPY "Use prebuilt MesaPy SGX executor" ON) option(EXECUTOR_BUILTIN "Compile with the Builtin executor" ON) option(EXECUTOR_MESAPY "Compile with the MesaPy executor" ON) option(EXECUTOR_WAMR "Compile with the WebAssembly Micro Runtime executor" ON) @@ -189,7 +188,6 @@ set(WAMR_OUTPUTS ${TEACLAVE_OUT_DIR}/libvmlib.a ) -if(USE_PREBUILT_MESAPY) add_custom_command( OUTPUT ${MESAPY_OUTPUTS} COMMAND @@ -197,21 +195,6 @@ add_custom_command( tar xzf mesapy-${MESAPY_VERSION}.tar.gz DEPENDS prep WORKING_DIRECTORY ${TEACLAVE_OUT_DIR}) -else() - add_custom_command( - OUTPUT ${MESAPY_OUTPUTS} - COMMAND - make sgx && - make -C sgx/examples/exec && - cp pypy/goal/libpypy-c.a - sgx/libffi/build_dir/lib/libffi.a - sgx/sgx_tlibc_ext/libsgx_tlibc_ext.a - sgx/sgx_ulibc/libsgx_ulibc.a - sgx/examples/exec/Enclave/src/ffi.o - ${TEACLAVE_OUT_DIR} - DEPENDS prep - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/mesapy) -endif() ExternalProject_Add(wamr_teaclave SOURCE_DIR ${WAMR_TEACLAVE_ROOT_DIR} @@ -237,16 +220,7 @@ add_custom_target(wamr ) # mesapy components -add_custom_command( - OUTPUT ${TEACLAVE_OUT_DIR}/acs_py_enclave.c - COMMAND - env ARGS PYTHONPATH=${PROJECT_SOURCE_DIR}/third_party/mesapy/sgx - PYPY_FFI_OUTDIR=${TEACLAVE_OUT_DIR} pypy - ${PROJECT_SOURCE_DIR}/services/access_control/python/ffi.py - DEPENDS prep ${PROJECT_SOURCE_DIR}/services/access_control/python/ffi.py - ${PROJECT_SOURCE_DIR}/services/access_control/python/acs_engine.py - COMMENT "Generating mesapy ffi stubs") -add_library(pycomponent STATIC ${TEACLAVE_OUT_DIR}/acs_py_enclave.c) +add_library(pycomponent STATIC ${PROJECT_SOURCE_DIR}/services/access_control/python/acs_py_enclave.c) set_target_properties(pycomponent PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${TEACLAVE_OUT_DIR}) target_compile_definitions(pycomponent PUBLIC SGX) @@ -366,4 +340,4 @@ add_cargo_build_target( EXTRA_CARGO_FLAGS ${LIBOS_EXTRA_CARGO_FLAGS} DEPENDS - ${LIBOS_DEPENDS}) \ No newline at end of file + ${LIBOS_DEPENDS}) diff --git a/cmake/TeaclaveUtils.cmake b/cmake/TeaclaveUtils.cmake index 6adb3772..00105469 100644 --- a/cmake/TeaclaveUtils.cmake +++ b/cmake/TeaclaveUtils.cmake @@ -69,8 +69,7 @@ function(init_submodules) endif() endif() - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/mesapy" - OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/rust-sgx-sdk" + if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/rust-sgx-sdk" OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime") message( FATAL_ERROR diff --git a/services/access_control/python/acs_py_enclave.c b/services/access_control/python/acs_py_enclave.c new file mode 100644 index 00000000..20eec4b7 --- /dev/null +++ b/services/access_control/python/acs_py_enclave.c @@ -0,0 +1,3191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/* + * DO NOT MODIFY THIS MANUALLY! This file was generated using pypy. + * To generate this file: + * 1. Get mesapy code from https://github.com/mesalock-linux/mesapy/tree/947fb3f598eede83ba0e33b5b5655b9a9597c2d8 + * 2. Run `PYTHONPATH=mesapy/sgx pypy ffi.py`. + */ + +#define _CFFI_USE_EMBEDDING +#define _CFFI_ + +/* We try to define Py_LIMITED_API before including Python.h. + + Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and + Py_REF_DEBUG are not defined. This is a best-effort approximation: + we can learn about Py_DEBUG from pyconfig.h, but it is unclear if + the same works for the other two macros. Py_DEBUG implies them, + but not the other way around. + + Issue #350 is still open: on Windows, the code here causes it to link + with PYTHON36.DLL (for example) instead of PYTHON3.DLL. A fix was + attempted in 164e526a5515 and 14ce6985e1c3, but reverted: virtualenv + does not make PYTHON3.DLL available, and so the "correctly" compiled + version would not run inside a virtualenv. We will re-apply the fix + after virtualenv has been fixed for some time. For explanation, see + issue #355. For a workaround if you want PYTHON3.DLL and don't worry + about virtualenv, see issue #350. See also 'py_limited_api' in + setuptools_ext.py. +*/ +#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API) +# include <pyconfig.h> +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +# define Py_LIMITED_API +# endif +#endif + +#include <Python.h> +#ifdef __cplusplus +extern "C" { +#endif +#include <stddef.h> + +/* This part is from file 'cffi/parse_c_type.h'. It is copied at the + beginning of C sources generated by CFFI's ffi.set_source(). */ + +typedef void *_cffi_opcode_t; + +#define _CFFI_OP(opcode, arg) (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8)) +#define _CFFI_GETOP(cffi_opcode) ((unsigned char)(uintptr_t)cffi_opcode) +#define _CFFI_GETARG(cffi_opcode) (((intptr_t)cffi_opcode) >> 8) + +#define _CFFI_OP_PRIMITIVE 1 +#define _CFFI_OP_POINTER 3 +#define _CFFI_OP_ARRAY 5 +#define _CFFI_OP_OPEN_ARRAY 7 +#define _CFFI_OP_STRUCT_UNION 9 +#define _CFFI_OP_ENUM 11 +#define _CFFI_OP_FUNCTION 13 +#define _CFFI_OP_FUNCTION_END 15 +#define _CFFI_OP_NOOP 17 +#define _CFFI_OP_BITFIELD 19 +#define _CFFI_OP_TYPENAME 21 +#define _CFFI_OP_CPYTHON_BLTN_V 23 // varargs +#define _CFFI_OP_CPYTHON_BLTN_N 25 // noargs +#define _CFFI_OP_CPYTHON_BLTN_O 27 // O (i.e. a single arg) +#define _CFFI_OP_CONSTANT 29 +#define _CFFI_OP_CONSTANT_INT 31 +#define _CFFI_OP_GLOBAL_VAR 33 +#define _CFFI_OP_DLOPEN_FUNC 35 +#define _CFFI_OP_DLOPEN_CONST 37 +#define _CFFI_OP_GLOBAL_VAR_F 39 +#define _CFFI_OP_EXTERN_PYTHON 41 + +#define _CFFI_PRIM_VOID 0 +#define _CFFI_PRIM_BOOL 1 +#define _CFFI_PRIM_CHAR 2 +#define _CFFI_PRIM_SCHAR 3 +#define _CFFI_PRIM_UCHAR 4 +#define _CFFI_PRIM_SHORT 5 +#define _CFFI_PRIM_USHORT 6 +#define _CFFI_PRIM_INT 7 +#define _CFFI_PRIM_UINT 8 +#define _CFFI_PRIM_LONG 9 +#define _CFFI_PRIM_ULONG 10 +#define _CFFI_PRIM_LONGLONG 11 +#define _CFFI_PRIM_ULONGLONG 12 +#define _CFFI_PRIM_FLOAT 13 +#define _CFFI_PRIM_DOUBLE 14 +#define _CFFI_PRIM_LONGDOUBLE 15 + +#define _CFFI_PRIM_WCHAR 16 +#define _CFFI_PRIM_INT8 17 +#define _CFFI_PRIM_UINT8 18 +#define _CFFI_PRIM_INT16 19 +#define _CFFI_PRIM_UINT16 20 +#define _CFFI_PRIM_INT32 21 +#define _CFFI_PRIM_UINT32 22 +#define _CFFI_PRIM_INT64 23 +#define _CFFI_PRIM_UINT64 24 +#define _CFFI_PRIM_INTPTR 25 +#define _CFFI_PRIM_UINTPTR 26 +#define _CFFI_PRIM_PTRDIFF 27 +#define _CFFI_PRIM_SIZE 28 +#define _CFFI_PRIM_SSIZE 29 +#define _CFFI_PRIM_INT_LEAST8 30 +#define _CFFI_PRIM_UINT_LEAST8 31 +#define _CFFI_PRIM_INT_LEAST16 32 +#define _CFFI_PRIM_UINT_LEAST16 33 +#define _CFFI_PRIM_INT_LEAST32 34 +#define _CFFI_PRIM_UINT_LEAST32 35 +#define _CFFI_PRIM_INT_LEAST64 36 +#define _CFFI_PRIM_UINT_LEAST64 37 +#define _CFFI_PRIM_INT_FAST8 38 +#define _CFFI_PRIM_UINT_FAST8 39 +#define _CFFI_PRIM_INT_FAST16 40 +#define _CFFI_PRIM_UINT_FAST16 41 +#define _CFFI_PRIM_INT_FAST32 42 +#define _CFFI_PRIM_UINT_FAST32 43 +#define _CFFI_PRIM_INT_FAST64 44 +#define _CFFI_PRIM_UINT_FAST64 45 +#define _CFFI_PRIM_INTMAX 46 +#define _CFFI_PRIM_UINTMAX 47 +#define _CFFI_PRIM_FLOATCOMPLEX 48 +#define _CFFI_PRIM_DOUBLECOMPLEX 49 +#define _CFFI_PRIM_CHAR16 50 +#define _CFFI_PRIM_CHAR32 51 + +#define _CFFI__NUM_PRIM 52 +#define _CFFI__UNKNOWN_PRIM (-1) +#define _CFFI__UNKNOWN_FLOAT_PRIM (-2) +#define _CFFI__UNKNOWN_LONG_DOUBLE (-3) + +#define _CFFI__IO_FILE_STRUCT (-1) + + +struct _cffi_global_s { + const char *name; + void *address; + _cffi_opcode_t type_op; + void *size_or_direct_fn; // OP_GLOBAL_VAR: size, or 0 if unknown + // OP_CPYTHON_BLTN_*: addr of direct function +}; + +struct _cffi_getconst_s { + unsigned long long value; + const struct _cffi_type_context_s *ctx; + int gindex; +}; + +struct _cffi_struct_union_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_STRUCT_UNION + int flags; // _CFFI_F_* flags below + size_t size; + int alignment; + int first_field_index; // -> _cffi_fields array + int num_fields; +}; +#define _CFFI_F_UNION 0x01 // is a union, not a struct +#define _CFFI_F_CHECK_FIELDS 0x02 // complain if fields are not in the + // "standard layout" or if some are missing +#define _CFFI_F_PACKED 0x04 // for CHECK_FIELDS, assume a packed struct +#define _CFFI_F_EXTERNAL 0x08 // in some other ffi.include() +#define _CFFI_F_OPAQUE 0x10 // opaque + +struct _cffi_field_s { + const char *name; + size_t field_offset; + size_t field_size; + _cffi_opcode_t field_type_op; +}; + +struct _cffi_enum_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_ENUM + int type_prim; // _CFFI_PRIM_xxx + const char *enumerators; // comma-delimited string +}; + +struct _cffi_typename_s { + const char *name; + int type_index; /* if opaque, points to a possibly artificial + OP_STRUCT which is itself opaque */ +}; + +struct _cffi_type_context_s { + _cffi_opcode_t *types; + const struct _cffi_global_s *globals; + const struct _cffi_field_s *fields; + const struct _cffi_struct_union_s *struct_unions; + const struct _cffi_enum_s *enums; + const struct _cffi_typename_s *typenames; + int num_globals; + int num_struct_unions; + int num_enums; + int num_typenames; + const char *const *includes; + int num_types; + int flags; /* future extension */ +}; + +struct _cffi_parse_info_s { + const struct _cffi_type_context_s *ctx; + _cffi_opcode_t *output; + unsigned int output_size; + size_t error_location; + const char *error_message; +}; + +struct _cffi_externpy_s { + const char *name; + size_t size_of_result; + void *reserved1, *reserved2; +}; + +#ifdef _CFFI_INTERNAL +static int parse_c_type(struct _cffi_parse_info_s *info, const char *input); +static int search_in_globals(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +static int search_in_struct_unions(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +#endif + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include <malloc.h> /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include <stdint.h> +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include <stdint.h> +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include <alloca.h> +# endif +#endif + +#ifdef __GNUC__ +# define _CFFI_UNUSED_FN __attribute__((unused)) +#else +# define _CFFI_UNUSED_FN /* nothing */ +#endif + +#ifdef __cplusplus +# ifndef _Bool + typedef bool _Bool; /* semi-hackish: C++ has no _Bool; bool is builtin */ +# endif +#endif + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, struct _cffi_ctypedescr *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + not used any more +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((_cffi_wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(_cffi_wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(struct _cffi_ctypedescr *, \ + PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[24]) +#define _CFFI_CPIDX 25 +#define _cffi_call_python \ + ((void(*)(struct _cffi_externpy_s *, char *))_cffi_exports[_CFFI_CPIDX]) +#define _cffi_to_c_wchar3216_t \ + ((int(*)(PyObject *))_cffi_exports[26]) +#define _cffi_from_c_wchar3216_t \ + ((PyObject *(*)(int))_cffi_exports[27]) +#define _CFFI_NUM_EXPORTS 28 + +struct _cffi_ctypedescr; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; + +#define _cffi_type(index) ( \ + assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \ + (struct _cffi_ctypedescr *)_cffi_types[index]) + +static PyObject *_cffi_init(const char *module_name, Py_ssize_t version, + const struct _cffi_type_context_s *ctx) +{ + PyObject *module, *o_arg, *new_module; + void *raw[] = { + (void *)module_name, + (void *)version, + (void *)_cffi_exports, + (void *)ctx, + }; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + o_arg = PyLong_FromVoidPtr((void *)raw); + if (o_arg == NULL) + goto failure; + + new_module = PyObject_CallMethod( + module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg); + + Py_DECREF(o_arg); + Py_DECREF(module); + return new_module; + + failure: + Py_XDECREF(module); + return NULL; +} + + +#ifdef HAVE_WCHAR_H +typedef wchar_t _cffi_wchar_t; +#else +typedef uint16_t _cffi_wchar_t; /* same random pick as _cffi_backend.c */ +#endif + +_CFFI_UNUSED_FN static uint16_t _cffi_to_c_char16_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 2) + return (uint16_t)_cffi_to_c_wchar_t(o); + else + return (uint16_t)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char16_t(uint16_t x) +{ + if (sizeof(_cffi_wchar_t) == 2) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +_CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 4) + return (int)_cffi_to_c_wchar_t(o); + else + return (int)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(int x) +{ + if (sizeof(_cffi_wchar_t) == 4) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t(x); +} + + +/********** end CPython-specific section **********/ +#else +_CFFI_UNUSED_FN +static void (*_cffi_call_python_org)(struct _cffi_externpy_s *, char *); +# define _cffi_call_python _cffi_call_python_org +#endif + + +#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0])) + +#define _cffi_prim_int(size, sign) \ + ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \ + (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \ + (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \ + (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \ + _CFFI__UNKNOWN_PRIM) + +#define _cffi_prim_float(size) \ + ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT : \ + (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE : \ + (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE : \ + _CFFI__UNKNOWN_FLOAT_PRIM) + +#define _cffi_check_int(got, got_nonpos, expected) \ + ((got_nonpos) == (expected <= 0) && \ + (got) == (unsigned long long)expected) + +#ifdef MS_WIN32 +# define _cffi_stdcall __stdcall +#else +# define _cffi_stdcall /* nothing */ +#endif + +#ifdef __cplusplus +} +#endif + +#define _CFFI_MODULE_NAME "acs_py_enclave" +static const char _CFFI_PYTHON_STARTUP_CODE[] = { +// # NB. this is not a string because of a size limit in MSVC +// # Licensed to the Apache Software Foundation (ASF) under one +35,32,76,105,99,101,110,115,101,100,32,116,111,32,116,104,101,32,65,112,97,99, +104,101,32,83,111,102,116,119,97,114,101,32,70,111,117,110,100,97,116,105,111, +110,32,40,65,83,70,41,32,117,110,100,101,114,32,111,110,101,10, +// # or more contributor license agreements. See the NOTICE file +35,32,111,114,32,109,111,114,101,32,99,111,110,116,114,105,98,117,116,111,114, +32,108,105,99,101,110,115,101,32,97,103,114,101,101,109,101,110,116,115,46,32, +32,83,101,101,32,116,104,101,32,78,79,84,73,67,69,32,102,105,108,101,10, +// # distributed with this work for additional information +35,32,100,105,115,116,114,105,98,117,116,101,100,32,119,105,116,104,32,116,104, +105,115,32,119,111,114,107,32,102,111,114,32,97,100,100,105,116,105,111,110, +97,108,32,105,110,102,111,114,109,97,116,105,111,110,10, +// # regarding copyright ownership. The ASF licenses this file +35,32,114,101,103,97,114,100,105,110,103,32,99,111,112,121,114,105,103,104,116, +32,111,119,110,101,114,115,104,105,112,46,32,32,84,104,101,32,65,83,70,32,108, +105,99,101,110,115,101,115,32,116,104,105,115,32,102,105,108,101,10, +// # to you under the Apache License, Version 2.0 (the +35,32,116,111,32,121,111,117,32,117,110,100,101,114,32,116,104,101,32,65,112, +97,99,104,101,32,76,105,99,101,110,115,101,44,32,86,101,114,115,105,111,110, +32,50,46,48,32,40,116,104,101,10, +// # "License"); you may not use this file except in compliance +35,32,34,76,105,99,101,110,115,101,34,41,59,32,121,111,117,32,109,97,121,32, +110,111,116,32,117,115,101,32,116,104,105,115,32,102,105,108,101,32,101,120, +99,101,112,116,32,105,110,32,99,111,109,112,108,105,97,110,99,101,10, +// # with the License. You may obtain a copy of the License at +35,32,119,105,116,104,32,116,104,101,32,76,105,99,101,110,115,101,46,32,32,89, +111,117,32,109,97,121,32,111,98,116,97,105,110,32,97,32,99,111,112,121,32,111, +102,32,116,104,101,32,76,105,99,101,110,115,101,32,97,116,10, +// # +35,10, +// # http://www.apache.org/licenses/LICENSE-2.0 +35,32,32,32,104,116,116,112,58,47,47,119,119,119,46,97,112,97,99,104,101,46, +111,114,103,47,108,105,99,101,110,115,101,115,47,76,73,67,69,78,83,69,45,50, +46,48,10, +// # +35,10, +// # Unless required by applicable law or agreed to in writing, +35,32,85,110,108,101,115,115,32,114,101,113,117,105,114,101,100,32,98,121,32, +97,112,112,108,105,99,97,98,108,101,32,108,97,119,32,111,114,32,97,103,114,101, +101,100,32,116,111,32,105,110,32,119,114,105,116,105,110,103,44,10, +// # software distributed under the License is distributed on an +35,32,115,111,102,116,119,97,114,101,32,100,105,115,116,114,105,98,117,116,101, +100,32,117,110,100,101,114,32,116,104,101,32,76,105,99,101,110,115,101,32,105, +115,32,100,105,115,116,114,105,98,117,116,101,100,32,111,110,32,97,110,10, +// # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +35,32,34,65,83,32,73,83,34,32,66,65,83,73,83,44,32,87,73,84,72,79,85,84,32,87, +65,82,82,65,78,84,73,69,83,32,79,82,32,67,79,78,68,73,84,73,79,78,83,32,79,70, +32,65,78,89,10, +// # KIND, either express or implied. See the License for the +35,32,75,73,78,68,44,32,101,105,116,104,101,114,32,101,120,112,114,101,115,115, +32,111,114,32,105,109,112,108,105,101,100,46,32,32,83,101,101,32,116,104,101, +32,76,105,99,101,110,115,101,32,102,111,114,32,116,104,101,10, +// # specific language governing permissions and limitations +35,32,115,112,101,99,105,102,105,99,32,108,97,110,103,117,97,103,101,32,103, +111,118,101,114,110,105,110,103,32,112,101,114,109,105,115,115,105,111,110,115, +32,97,110,100,32,108,105,109,105,116,97,116,105,111,110,115,10, +// # under the License. +35,32,117,110,100,101,114,32,116,104,101,32,76,105,99,101,110,115,101,46,10, +// +10, +// ############################################################################### +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,10, +// # Parser Combinators +35,32,80,97,114,115,101,114,32,67,111,109,98,105,110,97,116,111,114,115,10, +// ############################################################################### +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,10, +// class Pair(tuple): +99,108,97,115,115,32,80,97,105,114,40,116,117,112,108,101,41,58,10, +// def __new__(cls, a, b): +32,32,32,32,100,101,102,32,95,95,110,101,119,95,95,40,99,108,115,44,32,97,44, +32,98,41,58,10, +// return super(Pair, cls).__new__(cls, [a, b]) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,117,112,101,114,40,80, +97,105,114,44,32,99,108,115,41,46,95,95,110,101,119,95,95,40,99,108,115,44,32, +91,97,44,32,98,93,41,10, +// +10, +// class Either(object): +99,108,97,115,115,32,69,105,116,104,101,114,40,111,98,106,101,99,116,41,58,10, +// def __init__(self, left, right): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,108,101,102,116,44,32,114,105,103,104,116,41,58,10, +// self.__left = left +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,108,101,102,116,32,61,32,108, +101,102,116,10, +// self.__right = right +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,114,105,103,104,116,32,61,32, +114,105,103,104,116,10, +// +10, +// def left(self): +32,32,32,32,100,101,102,32,108,101,102,116,40,115,101,108,102,41,58,10, +// if not self.is_left(): +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,115,101,108,102,46,105,115, +95,108,101,102,116,40,41,58,10, +// raise ValueError('wrong extractor for either') +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101, +69,114,114,111,114,40,39,119,114,111,110,103,32,101,120,116,114,97,99,116,111, +114,32,102,111,114,32,101,105,116,104,101,114,39,41,10, +// return self.__left +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +108,101,102,116,10, +// +10, +// def right(self): +32,32,32,32,100,101,102,32,114,105,103,104,116,40,115,101,108,102,41,58,10, +// if not self.is_right(): +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,115,101,108,102,46,105,115, +95,114,105,103,104,116,40,41,58,10, +// raise ValueError('wrong extractor for either') +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101, +69,114,114,111,114,40,39,119,114,111,110,103,32,101,120,116,114,97,99,116,111, +114,32,102,111,114,32,101,105,116,104,101,114,39,41,10, +// return self.__right +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +114,105,103,104,116,10, +// +10, +// def is_right(self): +32,32,32,32,100,101,102,32,105,115,95,114,105,103,104,116,40,115,101,108,102, +41,58,10, +// return False +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,70,97,108,115,101,10, +// +10, +// def is_left(self): +32,32,32,32,100,101,102,32,105,115,95,108,101,102,116,40,115,101,108,102,41, +58,10, +// return False +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,70,97,108,115,101,10, +// +10, +// def get(self): +32,32,32,32,100,101,102,32,103,101,116,40,115,101,108,102,41,58,10, +// if self.is_right(): +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,114,105,103, +104,116,40,41,58,10, +// return self.right() +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102, +46,114,105,103,104,116,40,41,10, +// if self.is_left(): +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102, +116,40,41,58,10, +// return self.left() +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102, +46,108,101,102,116,40,41,10, +// raise ValueError('incomplete Either object') +32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101,69,114,114,111, +114,40,39,105,110,99,111,109,112,108,101,116,101,32,69,105,116,104,101,114,32, +111,98,106,101,99,116,39,41,10, +// +10, +// def __str__(self): +32,32,32,32,100,101,102,32,95,95,115,116,114,95,95,40,115,101,108,102,41,58, +10, +// if self.is_left(): +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102, +116,40,41,58,10, +// return 'Left(' + str(self.left()) + ')' +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,76,101,102, +116,40,39,32,43,32,115,116,114,40,115,101,108,102,46,108,101,102,116,40,41,41, +32,43,32,39,41,39,10, +// else: +32,32,32,32,32,32,32,32,101,108,115,101,58,10, +// return 'Right(' + str(self.right()) + ')' +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,82,105,103, +104,116,40,39,32,43,32,115,116,114,40,115,101,108,102,46,114,105,103,104,116, +40,41,41,32,43,32,39,41,39,10, +// +10, +// def __repr__(self): +32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41, +58,10, +// if self.is_left(): +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102, +116,40,41,58,10, +// return 'Left(' + repr(self.left()) + ')' +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,76,101,102, +116,40,39,32,43,32,114,101,112,114,40,115,101,108,102,46,108,101,102,116,40, +41,41,32,43,32,39,41,39,10, +// else: +32,32,32,32,32,32,32,32,101,108,115,101,58,10, +// return 'Right(' + repr(self.right()) + ')' +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,82,105,103, +104,116,40,39,32,43,32,114,101,112,114,40,115,101,108,102,46,114,105,103,104, +116,40,41,41,32,43,32,39,41,39,10, +// +10, +// class Left(Either): +99,108,97,115,115,32,76,101,102,116,40,69,105,116,104,101,114,41,58,10, +// def __init__(self, payload): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,112,97,121,108,111,97,100,41,58,10, +// super(Left, self).__init__(payload, None) +32,32,32,32,32,32,32,32,115,117,112,101,114,40,76,101,102,116,44,32,115,101, +108,102,41,46,95,95,105,110,105,116,95,95,40,112,97,121,108,111,97,100,44,32, +78,111,110,101,41,10, +// +10, +// def is_left(self): +32,32,32,32,100,101,102,32,105,115,95,108,101,102,116,40,115,101,108,102,41, +58,10, +// return True +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,84,114,117,101,10, +// +10, +// class Right(Either): +99,108,97,115,115,32,82,105,103,104,116,40,69,105,116,104,101,114,41,58,10, +// def __init__(self, payload): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,112,97,121,108,111,97,100,41,58,10, +// super(Right, self).__init__(None, payload) +32,32,32,32,32,32,32,32,115,117,112,101,114,40,82,105,103,104,116,44,32,115, +101,108,102,41,46,95,95,105,110,105,116,95,95,40,78,111,110,101,44,32,112,97, +121,108,111,97,100,41,10, +// +10, +// def is_right(self): +32,32,32,32,100,101,102,32,105,115,95,114,105,103,104,116,40,115,101,108,102, +41,58,10, +// return True +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,84,114,117,101,10, +// +10, +// class Stream(object): +99,108,97,115,115,32,83,116,114,101,97,109,40,111,98,106,101,99,116,41,58,10, +// WHITESPACES = [' ', '\t', '\r'] +32,32,32,32,87,72,73,84,69,83,80,65,67,69,83,32,61,32,91,39,32,39,44,32,39,92, +116,39,44,32,39,92,114,39,93,10, +// def __init__(self, items, pos = 0): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,105,116,101,109,115,44,32,112,111,115,32,61,32,48,41,58,10, +// self.__items = items +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,116,101,109,115,32,61,32, +105,116,101,109,115,10, +// self.__pos = pos +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,112,111,115,32,61,32,112,111, +115,10, +// +10, +// def accept_strlit(self, string): +32,32,32,32,100,101,102,32,97,99,99,101,112,116,95,115,116,114,108,105,116,40, +115,101,108,102,44,32,115,116,114,105,110,103,41,58,10, +// # Typically parsers want to skip white spaces except line breaks +32,32,32,32,32,32,32,32,35,32,84,121,112,105,99,97,108,108,121,32,112,97,114, +115,101,114,115,32,119,97,110,116,32,116,111,32,115,107,105,112,32,119,104,105, +116,101,32,115,112,97,99,101,115,32,101,120,99,101,112,116,32,108,105,110,101, +32,98,114,101,97,107,115,10, +// # In the future this should be configurable +32,32,32,32,32,32,32,32,35,32,73,110,32,116,104,101,32,102,117,116,117,114,101, +32,116,104,105,115,32,115,104,111,117,108,100,32,98,101,32,99,111,110,102,105, +103,117,114,97,98,108,101,10, +// pos = self.__pos +32,32,32,32,32,32,32,32,112,111,115,32,61,32,115,101,108,102,46,95,95,112,111, +115,10, +// l = len(self.__items) +32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,101,108,102,46,95,95, +105,116,101,109,115,41,10, +// while pos < l and self.__items[pos] in self.WHITESPACES: +32,32,32,32,32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,108,32,97, +110,100,32,115,101,108,102,46,95,95,105,116,101,109,115,91,112,111,115,93,32, +105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67,69,83,58,10, +// pos += 1 +32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10, +// +10, +// match_pos = 0 +32,32,32,32,32,32,32,32,109,97,116,99,104,95,112,111,115,32,61,32,48,10, +// l = len(string) +32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,116,114,105,110,103, +41,32,32,32,32,32,32,32,32,10, +// while match_pos < l and string[match_pos] in self.WHITESPACES: +32,32,32,32,32,32,32,32,119,104,105,108,101,32,109,97,116,99,104,95,112,111, +115,32,60,32,108,32,97,110,100,32,115,116,114,105,110,103,91,109,97,116,99,104, +95,112,111,115,93,32,105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67, +69,83,58,10, +// match_pos += 1 +32,32,32,32,32,32,32,32,32,32,32,32,109,97,116,99,104,95,112,111,115,32,43,61, +32,49,10, +// if pos < match_pos: +32,32,32,32,32,32,32,32,105,102,32,112,111,115,32,60,32,109,97,116,99,104,95, +112,111,115,58,10, +// raise ParsingError(self, 'expecting "{}"'.format(string)) +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105, +110,103,69,114,114,111,114,40,115,101,108,102,44,32,39,101,120,112,101,99,116, +105,110,103,32,34,123,125,34,39,46,102,111,114,109,97,116,40,115,116,114,105, +110,103,41,41,10, +// if match_pos: +32,32,32,32,32,32,32,32,105,102,32,109,97,116,99,104,95,112,111,115,58,10, +// string = string[match_pos:] +32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,105,110,103,32,61,32,115,116, +114,105,110,103,91,109,97,116,99,104,95,112,111,115,58,93,10, +// if self.__items.startswith(string, pos): +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,95,95,105,116,101,109, +115,46,115,116,97,114,116,115,119,105,116,104,40,115,116,114,105,110,103,44, +32,112,111,115,41,58,10, +// return Stream(self.__items, pos + len(string)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,114,101, +97,109,40,115,101,108,102,46,95,95,105,116,101,109,115,44,32,112,111,115,32, +43,32,108,101,110,40,115,116,114,105,110,103,41,41,10, +// raise ParsingError(self, 'expecting "{}"'.format(string)) +32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,110,103,69,114, +114,111,114,40,115,101,108,102,44,32,39,101,120,112,101,99,116,105,110,103,32, +34,123,125,34,39,46,102,111,114,109,97,116,40,115,116,114,105,110,103,41,41, +10, +// +10, +// def accept_matcher(self, matcher): +32,32,32,32,100,101,102,32,97,99,99,101,112,116,95,109,97,116,99,104,101,114, +40,115,101,108,102,44,32,109,97,116,99,104,101,114,41,58,10, +// pos = self.__pos +32,32,32,32,32,32,32,32,112,111,115,32,61,32,115,101,108,102,46,95,95,112,111, +115,10, +// l = len(self.__items) +32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,101,108,102,46,95,95, +105,116,101,109,115,41,10, +// while pos < l and self.__items[pos] in self.WHITESPACES: +32,32,32,32,32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,108,32,97, +110,100,32,115,101,108,102,46,95,95,105,116,101,109,115,91,112,111,115,93,32, +105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67,69,83,58,10, +// pos += 1 +32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10, +// +10, +// res = matcher(self.__items, pos) +32,32,32,32,32,32,32,32,114,101,115,32,61,32,109,97,116,99,104,101,114,40,115, +101,108,102,46,95,95,105,116,101,109,115,44,32,112,111,115,41,10, +// if res is None: +32,32,32,32,32,32,32,32,105,102,32,114,101,115,32,105,115,32,78,111,110,101, +58,10, +// raise ParsingError(self, 'matcher for {} failed'.format(matcher.__doc__)) +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105, +110,103,69,114,114,111,114,40,115,101,108,102,44,32,39,109,97,116,99,104,101, +114,32,102,111,114,32,123,125,32,102,97,105,108,101,100,39,46,102,111,114,109, +97,116,40,109,97,116,99,104,101,114,46,95,95,100,111,99,95,95,41,41,10, +// obj, npos = res +32,32,32,32,32,32,32,32,111,98,106,44,32,110,112,111,115,32,61,32,114,101,115, +10, +// return obj, Stream(self.__items, npos) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,111,98,106,44,32,83,116,114, +101,97,109,40,115,101,108,102,46,95,95,105,116,101,109,115,44,32,110,112,111, +115,41,10, +// +10, +// def end(self): +32,32,32,32,100,101,102,32,101,110,100,40,115,101,108,102,41,58,10, +// return self.__pos == len(self.__items) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +112,111,115,32,61,61,32,108,101,110,40,115,101,108,102,46,95,95,105,116,101, +109,115,41,10, +// +10, +// def pos(self): +32,32,32,32,100,101,102,32,112,111,115,40,115,101,108,102,41,58,10, +// return self.__pos +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +112,111,115,10, +// +10, +// def __repr__(self): +32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41, +58,10, +// line_start = self.__items.rfind('\n', 0, self.__pos) + 1 +32,32,32,32,32,32,32,32,108,105,110,101,95,115,116,97,114,116,32,61,32,115,101, +108,102,46,95,95,105,116,101,109,115,46,114,102,105,110,100,40,39,92,110,39, +44,32,48,44,32,115,101,108,102,46,95,95,112,111,115,41,32,43,32,49,10, +// line_end = self.__items.find('\n', self.__pos) +32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,115,101,108, +102,46,95,95,105,116,101,109,115,46,102,105,110,100,40,39,92,110,39,44,32,115, +101,108,102,46,95,95,112,111,115,41,10, +// if line_end == -1: +32,32,32,32,32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,61,61,32, +45,49,58,10, +// line_end = self.__pos +32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32, +115,101,108,102,46,95,95,112,111,115,10, +// +10, +// if line_end - line_start > 80: +32,32,32,32,32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,45,32,108, +105,110,101,95,115,116,97,114,116,32,62,32,56,48,58,10, +// line_start = max(line_start, self.__pos - 40) +32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,115,116,97,114,116,32, +61,32,109,97,120,40,108,105,110,101,95,115,116,97,114,116,44,32,115,101,108, +102,46,95,95,112,111,115,32,45,32,52,48,41,10, +// line_end = min(line_start + 80, len(self.__items)) +32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32, +109,105,110,40,108,105,110,101,95,115,116,97,114,116,32,43,32,56,48,44,32,108, +101,110,40,115,101,108,102,46,95,95,105,116,101,109,115,41,41,10, +// +10, +// return ''.join([ +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110, +40,91,10, +// self.__items[line_start:line_end], +32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,116,101,109, +115,91,108,105,110,101,95,115,116,97,114,116,58,108,105,110,101,95,101,110,100, +93,44,10, +// '\n', +32,32,32,32,32,32,32,32,32,32,32,32,39,92,110,39,44,10, +// ' ' * (self.__pos - line_start), +32,32,32,32,32,32,32,32,32,32,32,32,39,32,39,32,42,32,40,115,101,108,102,46, +95,95,112,111,115,32,45,32,108,105,110,101,95,115,116,97,114,116,41,44,10, +// '^', +32,32,32,32,32,32,32,32,32,32,32,32,39,94,39,44,10, +// ' ' * (line_end - self.__pos), +32,32,32,32,32,32,32,32,32,32,32,32,39,32,39,32,42,32,40,108,105,110,101,95, +101,110,100,32,45,32,115,101,108,102,46,95,95,112,111,115,41,44,10, +// '\nerror at character ', +32,32,32,32,32,32,32,32,32,32,32,32,39,92,110,101,114,114,111,114,32,97,116, +32,99,104,97,114,97,99,116,101,114,32,39,44,10, +// str(self.__pos), +32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,40,115,101,108,102,46,95,95, +112,111,115,41,44,10, +// ]) +32,32,32,32,32,32,32,32,93,41,10, +// +10, +// class State(object): +99,108,97,115,115,32,83,116,97,116,101,40,111,98,106,101,99,116,41,58,10, +// def __init__(self, stream, payload = None, success = True): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,115,116,114,101,97,109,44,32,112,97,121,108,111,97,100,32,61,32,78,111,110, +101,44,32,115,117,99,99,101,115,115,32,61,32,84,114,117,101,41,58,10, +// self.stream = stream +32,32,32,32,32,32,32,32,115,101,108,102,46,115,116,114,101,97,109,32,61,32,115, +116,114,101,97,109,10, +// self.payload = payload +32,32,32,32,32,32,32,32,115,101,108,102,46,112,97,121,108,111,97,100,32,61,32, +112,97,121,108,111,97,100,10, +// self.success = success +32,32,32,32,32,32,32,32,115,101,108,102,46,115,117,99,99,101,115,115,32,61,32, +115,117,99,99,101,115,115,10, +// +10, +// def __bool__(self): +32,32,32,32,100,101,102,32,95,95,98,111,111,108,95,95,40,115,101,108,102,41, +58,10, +// return self.success +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,115,117, +99,99,101,115,115,10, +// +10, +// def __nonzero__(self): +32,32,32,32,100,101,102,32,95,95,110,111,110,122,101,114,111,95,95,40,115,101, +108,102,41,58,10, +// return self.__bool__() +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +98,111,111,108,95,95,40,41,10, +// +10, +// def fmap(self, f): +32,32,32,32,100,101,102,32,102,109,97,112,40,115,101,108,102,44,32,102,41,58, +10, +// if self: +32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,58,10, +// return State(self.stream, f(self.payload)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116, +101,40,115,101,108,102,46,115,116,114,101,97,109,44,32,102,40,115,101,108,102, +46,112,97,121,108,111,97,100,41,41,10, +// return self +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,10, +// +10, +// class ParsingError(Exception): +99,108,97,115,115,32,80,97,114,115,105,110,103,69,114,114,111,114,40,69,120, +99,101,112,116,105,111,110,41,58,10, +// def __init__(self, stream, msg = ''): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,115,116,114,101,97,109,44,32,109,115,103,32,61,32,39,39,41,58,10, +// super(ParsingError, self).__init__(msg) +32,32,32,32,32,32,32,32,115,117,112,101,114,40,80,97,114,115,105,110,103,69, +114,114,111,114,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,109, +115,103,41,10, +// self.stream = stream +32,32,32,32,32,32,32,32,115,101,108,102,46,115,116,114,101,97,109,32,61,32,115, +116,114,101,97,109,10, +// +10, +// def __repr__(self): +32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41, +58,10, +// return repr(self.stream) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,114,101,112,114,40,115,101, +108,102,46,115,116,114,101,97,109,41,10, +// +10, +// class Parser(object): +99,108,97,115,115,32,80,97,114,115,101,114,40,111,98,106,101,99,116,41,58,10, +// def __init__(self): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,41, +58,10, +// pass +32,32,32,32,32,32,32,32,112,97,115,115,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// raise NotImplementedError("pure abstract parser cannot be called") +32,32,32,32,32,32,32,32,114,97,105,115,101,32,78,111,116,73,109,112,108,101, +109,101,110,116,101,100,69,114,114,111,114,40,34,112,117,114,101,32,97,98,115, +116,114,97,99,116,32,112,97,114,115,101,114,32,99,97,110,110,111,116,32,98,101, +32,99,97,108,108,101,100,34,41,10, +// +10, +// def parse_from(self, stream): +32,32,32,32,100,101,102,32,112,97,114,115,101,95,102,114,111,109,40,115,101, +108,102,44,32,115,116,114,101,97,109,41,58,10, +// n_state = self(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,40, +115,116,114,101,97,109,41,10, +// if not n_state: +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101, +58,10, +// raise ParsingError(n_state.stream, n_state.payload) +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105, +110,103,69,114,114,111,114,40,110,95,115,116,97,116,101,46,115,116,114,101,97, +109,44,32,110,95,115,116,97,116,101,46,112,97,121,108,111,97,100,41,10, +// elif not n_state.stream.end(): +32,32,32,32,32,32,32,32,101,108,105,102,32,110,111,116,32,110,95,115,116,97, +116,101,46,115,116,114,101,97,109,46,101,110,100,40,41,58,10, +// raise ParsingError(n_state.stream, 'trailing unparsable input') +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105, +110,103,69,114,114,111,114,40,110,95,115,116,97,116,101,46,115,116,114,101,97, +109,44,32,39,116,114,97,105,108,105,110,103,32,117,110,112,97,114,115,97,98, +108,101,32,105,110,112,117,116,39,41,10, +// return n_state +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,97,116,101, +10, +// +10, +// def fail(self, exception): +32,32,32,32,100,101,102,32,102,97,105,108,40,115,101,108,102,44,32,101,120,99, +101,112,116,105,111,110,41,58,10, +// return State(exception.stream, str(exception), False) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,101, +120,99,101,112,116,105,111,110,46,115,116,114,101,97,109,44,32,115,116,114,40, +101,120,99,101,112,116,105,111,110,41,44,32,70,97,108,115,101,41,10, +// +10, +// def ignore(self): +32,32,32,32,100,101,102,32,105,103,110,111,114,101,40,115,101,108,102,41,58, +10, +// return Ignore(self) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,103,110,111,114,101,40, +115,101,108,102,41,10, +// +10, +// def __or__(self, p): +32,32,32,32,100,101,102,32,95,95,111,114,95,95,40,115,101,108,102,44,32,112, +41,58,10, +// return Or(self, p) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,79,114,40,115,101,108,102, +44,32,112,41,10, +// +10, +// def __add__(self, p): +32,32,32,32,100,101,102,32,95,95,97,100,100,95,95,40,115,101,108,102,44,32,112, +41,58,10, +// if isinstance(self, Ignore) and isinstance(p, Ignore): +32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40, +115,101,108,102,44,32,73,103,110,111,114,101,41,32,97,110,100,32,105,115,105, +110,115,116,97,110,99,101,40,112,44,32,73,103,110,111,114,101,41,58,10, +// return Ignore(Concat(self, p)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,103,110,111, +114,101,40,67,111,110,99,97,116,40,115,101,108,102,44,32,112,41,41,10, +// else: +32,32,32,32,32,32,32,32,101,108,115,101,58,10, +// return Concat(self, p) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,67,111,110,99, +97,116,40,115,101,108,102,44,32,112,41,10, +// +10, +// def __invert__(self): +32,32,32,32,100,101,102,32,95,95,105,110,118,101,114,116,95,95,40,115,101,108, +102,41,58,10, +// return Rep(self) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,82,101,112,40,115,101,108, +102,41,10, +// +10, +// def __neg__(self): +32,32,32,32,100,101,102,32,95,95,110,101,103,95,95,40,115,101,108,102,41,58, +10, +// return Optional(self) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,79,112,116,105,111,110,97, +108,40,115,101,108,102,41,10, +// +10, +// def __pow__(self, f): +32,32,32,32,100,101,102,32,95,95,112,111,119,95,95,40,115,101,108,102,44,32, +102,41,58,10, +// return Apply(self, f) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,65,112,112,108,121,40,115, +101,108,102,44,32,102,41,10, +// +10, +// class Optional(Parser): +99,108,97,115,115,32,79,112,116,105,111,110,97,108,40,80,97,114,115,101,114, +41,58,10, +// def __init__(self, opt): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,111,112,116,41,58,10, +// super(Optional, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,79,112,116,105,111,110,97,108, +44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__opt = opt +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,111,112,116,32,61,32,111,112, +116,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// n_state = self.__opt(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,111,112,116,40,115,116,114,101,97,109,41,10, +// if n_state: +32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10, +// return n_state.fmap(lambda x: Left(x)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116, +97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,76,101,102, +116,40,120,41,41,10, +// return State(stream, Right(None)) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,115, +116,114,101,97,109,44,32,82,105,103,104,116,40,78,111,110,101,41,41,10, +// +10, +// class StrLiteral(Parser): +99,108,97,115,115,32,83,116,114,76,105,116,101,114,97,108,40,80,97,114,115,101, +114,41,58,10, +// def __init__(self, string): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,115,116,114,105,110,103,41,58,10, +// super(StrLiteral, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,83,116,114,76,105,116,101,114, +97,108,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__string = string +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,115,116,114,105,110,103,32, +61,32,115,116,114,105,110,103,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// if stream.end(): +32,32,32,32,32,32,32,32,105,102,32,115,116,114,101,97,109,46,101,110,100,40, +41,58,10, +// return self.fail(ParsingError( +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102, +46,102,97,105,108,40,80,97,114,115,105,110,103,69,114,114,111,114,40,10, +// stream, 'insufficient input, expecting {}'.format(self.__string)) +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,44,32, +39,105,110,115,117,102,102,105,99,105,101,110,116,32,105,110,112,117,116,44, +32,101,120,112,101,99,116,105,110,103,32,123,125,39,46,102,111,114,109,97,116, +40,115,101,108,102,46,95,95,115,116,114,105,110,103,41,41,10, +// ) +32,32,32,32,32,32,32,32,32,32,32,32,41,10, +// try: +32,32,32,32,32,32,32,32,116,114,121,58,10, +// n_stream = stream.accept_strlit(self.__string) +32,32,32,32,32,32,32,32,32,32,32,32,110,95,115,116,114,101,97,109,32,61,32,115, +116,114,101,97,109,46,97,99,99,101,112,116,95,115,116,114,108,105,116,40,115, +101,108,102,46,95,95,115,116,114,105,110,103,41,10, +// except ParsingError as e: +32,32,32,32,32,32,32,32,101,120,99,101,112,116,32,80,97,114,115,105,110,103, +69,114,114,111,114,32,97,115,32,101,58,10, +// return self.fail(e) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102, +46,102,97,105,108,40,101,41,10, +// +10, +// return State(n_stream, self.__string) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110, +95,115,116,114,101,97,109,44,32,115,101,108,102,46,95,95,115,116,114,105,110, +103,41,10, +// +10, +// class CustomMatcher(Parser): +99,108,97,115,115,32,67,117,115,116,111,109,77,97,116,99,104,101,114,40,80,97, +114,115,101,114,41,58,10, +// def __init__(self, matcher): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,109,97,116,99,104,101,114,41,58,10, +// super(CustomMatcher, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,67,117,115,116,111,109,77,97, +116,99,104,101,114,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40, +41,10, +// self.__matcher = matcher +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,109,97,116,99,104,101,114,32, +61,32,109,97,116,99,104,101,114,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// try: +32,32,32,32,32,32,32,32,116,114,121,58,10, +// res = stream.accept_matcher(self.__matcher) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,115,32,61,32,115,116,114,101,97, +109,46,97,99,99,101,112,116,95,109,97,116,99,104,101,114,40,115,101,108,102, +46,95,95,109,97,116,99,104,101,114,41,10, +// except ParsingError as e: +32,32,32,32,32,32,32,32,101,120,99,101,112,116,32,80,97,114,115,105,110,103, +69,114,114,111,114,32,97,115,32,101,58,10, +// return self.fail(e) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102, +46,102,97,105,108,40,101,41,10, +// +10, +// obj, n_stream = res +32,32,32,32,32,32,32,32,111,98,106,44,32,110,95,115,116,114,101,97,109,32,61, +32,114,101,115,10, +// return State(n_stream, obj) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110, +95,115,116,114,101,97,109,44,32,111,98,106,41,10, +// +10, +// class Concat(Parser): +99,108,97,115,115,32,67,111,110,99,97,116,40,80,97,114,115,101,114,41,58,10, +// def __init__(self, c1, c2): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,99,49,44,32,99,50,41,58,10, +// super(Concat, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,67,111,110,99,97,116,44,32,115, +101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// assert not isinstance(self, Ignore) or not isinstance(p, Ignore) +32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,110,111,116,32,105,115,105, +110,115,116,97,110,99,101,40,115,101,108,102,44,32,73,103,110,111,114,101,41, +32,111,114,32,110,111,116,32,105,115,105,110,115,116,97,110,99,101,40,112,44, +32,73,103,110,111,114,101,41,10, +// self.__first = c1 +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,105,114,115,116,32,61,32, +99,49,10, +// self.__second = c2 +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,115,101,99,111,110,100,32,61, +32,99,50,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// n_state = self.__first(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,102,105,114,115,116,40,115,116,114,101,97,109,41,10, +// if not n_state: +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101, +58,10, +// return n_state +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116, +97,116,101,10, +// p1 = n_state.payload +32,32,32,32,32,32,32,32,112,49,32,61,32,110,95,115,116,97,116,101,46,112,97, +121,108,111,97,100,10, +// n_state = self.__second(n_state.stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,115,101,99,111,110,100,40,110,95,115,116,97,116,101,46,115,116,114,101, +97,109,41,10, +// if not n_state: +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101, +58,10, +// return n_state +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116, +97,116,101,10, +// p2 = n_state.payload +32,32,32,32,32,32,32,32,112,50,32,61,32,110,95,115,116,97,116,101,46,112,97, +121,108,111,97,100,10, +// +10, +// if isinstance(self.__first, Ignore): +32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40, +115,101,108,102,46,95,95,102,105,114,115,116,44,32,73,103,110,111,114,101,41, +58,10, +// return State(n_state.stream, p2) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116, +101,40,110,95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,112,50,41,10, +// if isinstance(self.__second, Ignore): +32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40, +115,101,108,102,46,95,95,115,101,99,111,110,100,44,32,73,103,110,111,114,101, +41,58,10, +// return State(n_state.stream, p1) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116, +101,40,110,95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,112,49,41,10, +// # The construction of Concat ensures that at least +32,32,32,32,32,32,32,32,35,32,84,104,101,32,99,111,110,115,116,114,117,99,116, +105,111,110,32,111,102,32,67,111,110,99,97,116,32,101,110,115,117,114,101,115, +32,116,104,97,116,32,97,116,32,108,101,97,115,116,10, +// # one of this children is not Ignore +32,32,32,32,32,32,32,32,35,32,111,110,101,32,111,102,32,116,104,105,115,32,99, +104,105,108,100,114,101,110,32,105,115,32,110,111,116,32,73,103,110,111,114, +101,10, +// return State(n_state.stream, Pair(p1, p2)) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110, +95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,80,97,105,114,40,112,49, +44,32,112,50,41,41,10, +// +10, +// class Or(Parser): +99,108,97,115,115,32,79,114,40,80,97,114,115,101,114,41,58,10, +// def __init__(self, c1, c2): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,99,49,44,32,99,50,41,58,10, +// super(Or, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,79,114,44,32,115,101,108,102, +41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__if = c1 +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,102,32,61,32,99,49,10, +// self.__else = c2 +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,101,108,115,101,32,61,32,99, +50,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// n_state = self.__if(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,105,102,40,115,116,114,101,97,109,41,10, +// if n_state: +32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10, +// return n_state.fmap(lambda x: Left(x)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116, +97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,76,101,102, +116,40,120,41,41,10, +// n_state = self.__else(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,101,108,115,101,40,115,116,114,101,97,109,41,10, +// if n_state: +32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10, +// return n_state.fmap(lambda x: Right(x)) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116, +97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,82,105,103, +104,116,40,120,41,41,10, +// return n_state +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,97,116,101, +10, +// +10, +// class Rep(Parser): +99,108,97,115,115,32,82,101,112,40,80,97,114,115,101,114,41,58,10, +// def __init__(self, c): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,99,41,58,10, +// super(Rep, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,82,101,112,44,32,115,101,108, +102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__loop = c +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,108,111,111,112,32,61,32,99, +10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// payload = [] +32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,32,61,32,91,93,10, +// +10, +// n_state = self.__loop(stream) +32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46, +95,95,108,111,111,112,40,115,116,114,101,97,109,41,10, +// if n_state: +32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10, +// payload.append(n_state.payload) +32,32,32,32,32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,46,97,112,112, +101,110,100,40,110,95,115,116,97,116,101,46,112,97,121,108,111,97,100,41,10, +// stream = n_state.stream +32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,32,61,32,110,95,115, +116,97,116,101,46,115,116,114,101,97,109,10, +// n_state = self(stream) +32,32,32,32,32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101, +108,102,40,115,116,114,101,97,109,41,10, +// if n_state: +32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58, +10, +// payload = payload + n_state.payload +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,32, +61,32,112,97,121,108,111,97,100,32,43,32,110,95,115,116,97,116,101,46,112,97, +121,108,111,97,100,10, +// stream = n_state.stream +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,32,61, +32,110,95,115,116,97,116,101,46,115,116,114,101,97,109,10, +// return State(stream, payload) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,115, +116,114,101,97,109,44,32,112,97,121,108,111,97,100,41,10, +// +10, +// class Apply(Parser): +99,108,97,115,115,32,65,112,112,108,121,40,80,97,114,115,101,114,41,58,10, +// def __init__(self, base, f): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,98,97,115,101,44,32,102,41,58,10, +// super(Apply, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,65,112,112,108,121,44,32,115, +101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__base = base +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,98,97,115,101,32,61,32,98,97, +115,101,10, +// self.__trans = f +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,114,97,110,115,32,61,32, +102,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// return self.__base(stream).fmap(self.__trans) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +98,97,115,101,40,115,116,114,101,97,109,41,46,102,109,97,112,40,115,101,108, +102,46,95,95,116,114,97,110,115,41,10, +// +10, +// class Ignore(Parser): +99,108,97,115,115,32,73,103,110,111,114,101,40,80,97,114,115,101,114,41,58,10, +// def __init__(self, base): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,98,97,115,101,41,58,10, +// super(Ignore, self).__init__() +32,32,32,32,32,32,32,32,115,117,112,101,114,40,73,103,110,111,114,101,44,32, +115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10, +// self.__base = base +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,98,97,115,101,32,61,32,98,97, +115,101,10, +// +10, +// def __call__(self, stream): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +115,116,114,101,97,109,41,58,10, +// return self.__base(stream) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +98,97,115,101,40,115,116,114,101,97,109,41,10, +// +10, +// ############################################################################### +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,10, +// # Grammars for PERM model configuration +35,32,71,114,97,109,109,97,114,115,32,102,111,114,32,80,69,82,77,32,109,111, +100,101,108,32,99,111,110,102,105,103,117,114,97,116,105,111,110,32,10, +// ############################################################################### +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,10, +// from operator import or_, add +102,114,111,109,32,111,112,101,114,97,116,111,114,32,105,109,112,111,114,116, +32,111,114,95,44,32,97,100,100,10, +// +10, +// def extract(nested_or): +100,101,102,32,101,120,116,114,97,99,116,40,110,101,115,116,101,100,95,111,114, +41,58,10, +// while isinstance(nested_or, Either): +32,32,32,32,119,104,105,108,101,32,105,115,105,110,115,116,97,110,99,101,40, +110,101,115,116,101,100,95,111,114,44,32,69,105,116,104,101,114,41,58,10, +// nested_or = nested_or.left() if nested_or.is_left() else nested_or.right() +32,32,32,32,32,32,32,32,110,101,115,116,101,100,95,111,114,32,61,32,110,101, +115,116,101,100,95,111,114,46,108,101,102,116,40,41,32,105,102,32,110,101,115, +116,101,100,95,111,114,46,105,115,95,108,101,102,116,40,41,32,101,108,115,101, +32,110,101,115,116,101,100,95,111,114,46,114,105,103,104,116,40,41,10, +// return nested_or +32,32,32,32,114,101,116,117,114,110,32,110,101,115,116,101,100,95,111,114,10, +// +10, +// def flatten(nested_concat): +100,101,102,32,102,108,97,116,116,101,110,40,110,101,115,116,101,100,95,99,111, +110,99,97,116,41,58,10, +// res = [] +32,32,32,32,114,101,115,32,61,32,91,93,10, +// +10, +// def pre_order(pair, res): +32,32,32,32,100,101,102,32,112,114,101,95,111,114,100,101,114,40,112,97,105, +114,44,32,114,101,115,41,58,10, +// if isinstance(pair, Pair): +32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40, +112,97,105,114,44,32,80,97,105,114,41,58,10, +// pre_order(pair[0], res) +32,32,32,32,32,32,32,32,32,32,32,32,112,114,101,95,111,114,100,101,114,40,112, +97,105,114,91,48,93,44,32,114,101,115,41,10, +// pre_order(pair[1], res) +32,32,32,32,32,32,32,32,32,32,32,32,112,114,101,95,111,114,100,101,114,40,112, +97,105,114,91,49,93,44,32,114,101,115,41,10, +// else: +32,32,32,32,32,32,32,32,101,108,115,101,58,10, +// res.append(pair) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,115,46,97,112,112,101,110,100,40, +112,97,105,114,41,10, +// +10, +// pre_order(nested_concat, res) +32,32,32,32,112,114,101,95,111,114,100,101,114,40,110,101,115,116,101,100,95, +99,111,110,99,97,116,44,32,114,101,115,41,10, +// return res +32,32,32,32,114,101,116,117,114,110,32,114,101,115,10, +// +10, +// def one_of(parsers): +100,101,102,32,111,110,101,95,111,102,40,112,97,114,115,101,114,115,41,58,10, +// nested = reduce(or_, parsers) +32,32,32,32,110,101,115,116,101,100,32,61,32,114,101,100,117,99,101,40,111,114, +95,44,32,112,97,114,115,101,114,115,41,10, +// return nested ** extract +32,32,32,32,114,101,116,117,114,110,32,110,101,115,116,101,100,32,42,42,32,101, +120,116,114,97,99,116,10, +// +10, +// def join(sl): +100,101,102,32,106,111,105,110,40,115,108,41,58,10, +// return ''.join(sl) +32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110,40,115,108,41, +10, +// +10, +// def rep_with_sep(to_rep, sep): +100,101,102,32,114,101,112,95,119,105,116,104,95,115,101,112,40,116,111,95,114, +101,112,44,32,115,101,112,41,58,10, +// if not isinstance(sep, Ignore): +32,32,32,32,105,102,32,110,111,116,32,105,115,105,110,115,116,97,110,99,101, +40,115,101,112,44,32,73,103,110,111,114,101,41,58,10, +// sep = sep.ignore() +32,32,32,32,32,32,32,32,115,101,112,32,61,32,115,101,112,46,105,103,110,111, +114,101,40,41,10, +// r = to_rep + ~(sep + to_rep) +32,32,32,32,114,32,61,32,116,111,95,114,101,112,32,43,32,126,40,115,101,112, +32,43,32,116,111,95,114,101,112,41,10, +// r = r ** (lambda x: [x[0]] + x[1]) +32,32,32,32,114,32,61,32,114,32,42,42,32,40,108,97,109,98,100,97,32,120,58,32, +91,120,91,48,93,93,32,43,32,120,91,49,93,41,10, +// return r +32,32,32,32,114,101,116,117,114,110,32,114,10, +// +10, +// ALPHA = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') +65,76,80,72,65,32,61,32,115,101,116,40,39,97,98,99,100,101,102,103,104,105,106, +107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,65,66,67,68, +69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,39,41,10, +// DIGIT = set('0123456789') +68,73,71,73,84,32,61,32,115,101,116,40,39,48,49,50,51,52,53,54,55,56,57,39,41, +10, +// ALPHA_DIGIT = ALPHA | DIGIT +65,76,80,72,65,95,68,73,71,73,84,32,61,32,65,76,80,72,65,32,124,32,68,73,71, +73,84,10, +// +10, +// Alpha = one_of(map(StrLiteral, ALPHA)) +65,108,112,104,97,32,61,32,111,110,101,95,111,102,40,109,97,112,40,83,116,114, +76,105,116,101,114,97,108,44,32,65,76,80,72,65,41,41,10, +// Digit = one_of(map(StrLiteral, DIGIT)) +68,105,103,105,116,32,61,32,111,110,101,95,111,102,40,109,97,112,40,83,116,114, +76,105,116,101,114,97,108,44,32,68,73,71,73,84,41,41,10, +// +10, +// Equal, Comma, Dot = [StrLiteral(c).ignore() for c in ['=', ',', '.']] +69,113,117,97,108,44,32,67,111,109,109,97,44,32,68,111,116,32,61,32,91,83,116, +114,76,105,116,101,114,97,108,40,99,41,46,105,103,110,111,114,101,40,41,32,102, +111,114,32,99,32,105,110,32,91,39,61,39,44,32,39,44,39,44,32,39,46,39,93,93, +10, +// Underscore = StrLiteral('_') +85,110,100,101,114,115,99,111,114,101,32,61,32,83,116,114,76,105,116,101,114, +97,108,40,39,95,39,41,10, +// NewLine = (~ StrLiteral('\n')).ignore() +78,101,119,76,105,110,101,32,61,32,40,126,32,83,116,114,76,105,116,101,114,97, +108,40,39,92,110,39,41,41,46,105,103,110,111,114,101,40,41,10, +// +10, +// def identifier_matcher(text, pos): +100,101,102,32,105,100,101,110,116,105,102,105,101,114,95,109,97,116,99,104, +101,114,40,116,101,120,116,44,32,112,111,115,41,58,10, +// """identifier""" +32,32,32,32,34,34,34,105,100,101,110,116,105,102,105,101,114,34,34,34,10, +// end = len(text) +32,32,32,32,101,110,100,32,61,32,108,101,110,40,116,101,120,116,41,10, +// start = pos +32,32,32,32,115,116,97,114,116,32,61,32,112,111,115,10, +// if pos >= end: +32,32,32,32,105,102,32,112,111,115,32,62,61,32,101,110,100,58,10, +// return None +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10, +// first = text[pos] +32,32,32,32,102,105,114,115,116,32,61,32,116,101,120,116,91,112,111,115,93,10, +// if first != '_' and first not in ALPHA: +32,32,32,32,105,102,32,102,105,114,115,116,32,33,61,32,39,95,39,32,97,110,100, +32,102,105,114,115,116,32,110,111,116,32,105,110,32,65,76,80,72,65,58,10, +// return None +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10, +// pos += 1 +32,32,32,32,112,111,115,32,43,61,32,49,10, +// while pos < end: +32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,101,110,100,58,10, +// char = text[pos] +32,32,32,32,32,32,32,32,99,104,97,114,32,61,32,116,101,120,116,91,112,111,115, +93,10, +// if char == '_' or char in ALPHA_DIGIT: +32,32,32,32,32,32,32,32,105,102,32,99,104,97,114,32,61,61,32,39,95,39,32,111, +114,32,99,104,97,114,32,105,110,32,65,76,80,72,65,95,68,73,71,73,84,58,10, +// pos += 1 +32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10, +// else: +32,32,32,32,32,32,32,32,101,108,115,101,58,10, +// break +32,32,32,32,32,32,32,32,32,32,32,32,98,114,101,97,107,10, +// return text[start:pos], pos +32,32,32,32,114,101,116,117,114,110,32,116,101,120,116,91,115,116,97,114,116, +58,112,111,115,93,44,32,112,111,115,10, +// +10, +// Identifier = CustomMatcher(identifier_matcher) +73,100,101,110,116,105,102,105,101,114,32,61,32,67,117,115,116,111,109,77,97, +116,99,104,101,114,40,105,100,101,110,116,105,102,105,101,114,95,109,97,116, +99,104,101,114,41,10, +// +10, +// IdTuple = rep_with_sep(Identifier, Comma) +73,100,84,117,112,108,101,32,61,32,114,101,112,95,119,105,116,104,95,115,101, +112,40,73,100,101,110,116,105,102,105,101,114,44,32,67,111,109,109,97,41,10, +// +10, +// Definition = Identifier + Equal + IdTuple + NewLine +68,101,102,105,110,105,116,105,111,110,32,61,32,73,100,101,110,116,105,102,105, +101,114,32,43,32,69,113,117,97,108,32,43,32,73,100,84,117,112,108,101,32,43, +32,78,101,119,76,105,110,101,10, +// +10, +// Relation = Identifier + Equal + IdTuple + NewLine +82,101,108,97,116,105,111,110,32,61,32,73,100,101,110,116,105,102,105,101,114, +32,43,32,69,113,117,97,108,32,43,32,73,100,84,117,112,108,101,32,43,32,78,101, +119,76,105,110,101,10, +// Relation = Relation ** (lambda x: (x[0], 1 + len(x[1][1]))) +82,101,108,97,116,105,111,110,32,61,32,82,101,108,97,116,105,111,110,32,42,42, +32,40,108,97,109,98,100,97,32,120,58,32,40,120,91,48,93,44,32,49,32,43,32,108, +101,110,40,120,91,49,93,91,49,93,41,41,41,10, +// +10, +// def pyparser_matcher(text, pos): +100,101,102,32,112,121,112,97,114,115,101,114,95,109,97,116,99,104,101,114,40, +116,101,120,116,44,32,112,111,115,41,58,10, +// """syntactically correct python code""" +32,32,32,32,34,34,34,115,121,110,116,97,99,116,105,99,97,108,108,121,32,99,111, +114,114,101,99,116,32,112,121,116,104,111,110,32,99,111,100,101,34,34,34,10, +// line_end = text.find('\n', pos) +32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,116,101,120,116,46,102,105, +110,100,40,39,92,110,39,44,32,112,111,115,41,10, +// if line_end == -1: +32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,61,61,32,45,49,58,10, +// return None +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10, +// try: +32,32,32,32,116,114,121,58,10, +// c = compile(text[pos:line_end], '__abac_model__.py', 'eval') +32,32,32,32,32,32,32,32,99,32,61,32,99,111,109,112,105,108,101,40,116,101,120, +116,91,112,111,115,58,108,105,110,101,95,101,110,100,93,44,32,39,95,95,97,98, +97,99,95,109,111,100,101,108,95,95,46,112,121,39,44,32,39,101,118,97,108,39, +41,10, +// except SyntaxError: +32,32,32,32,101,120,99,101,112,116,32,83,121,110,116,97,120,69,114,114,111,114, +58,10, +// return None +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10, +// return c, line_end +32,32,32,32,114,101,116,117,114,110,32,99,44,32,108,105,110,101,95,101,110,100, +10, +// +10, +// PyExpr = CustomMatcher(pyparser_matcher) +80,121,69,120,112,114,32,61,32,67,117,115,116,111,109,77,97,116,99,104,101,114, +40,112,121,112,97,114,115,101,114,95,109,97,116,99,104,101,114,41,10, +// Matcher = Identifier + Equal + PyExpr + NewLine +77,97,116,99,104,101,114,32,61,32,73,100,101,110,116,105,102,105,101,114,32, +43,32,69,113,117,97,108,32,43,32,80,121,69,120,112,114,32,43,32,78,101,119,76, +105,110,101,10, +// +10, +// RequestDefHeader = StrLiteral('[requests]') + NewLine +82,101,113,117,101,115,116,68,101,102,72,101,97,100,101,114,32,61,32,83,116, +114,76,105,116,101,114,97,108,40,39,91,114,101,113,117,101,115,116,115,93,39, +41,32,43,32,78,101,119,76,105,110,101,10, +// TermDefHeader = StrLiteral('[terms]') + NewLine +84,101,114,109,68,101,102,72,101,97,100,101,114,32,32,32,32,61,32,83,116,114, +76,105,116,101,114,97,108,40,39,91,116,101,114,109,115,93,39,41,32,43,32,78, +101,119,76,105,110,101,10, +// MatchersHeader = StrLiteral('[matchers]') + NewLine +77,97,116,99,104,101,114,115,72,101,97,100,101,114,32,32,32,61,32,83,116,114, +76,105,116,101,114,97,108,40,39,91,109,97,116,99,104,101,114,115,93,39,41,32, +43,32,78,101,119,76,105,110,101,10, +// +10, +// RequestDefSec = RequestDefHeader.ignore() + ~Definition +82,101,113,117,101,115,116,68,101,102,83,101,99,32,61,32,82,101,113,117,101, +115,116,68,101,102,72,101,97,100,101,114,46,105,103,110,111,114,101,40,41,32, +43,32,126,68,101,102,105,110,105,116,105,111,110,10, +// TermDefSec = TermDefHeader.ignore() + ~Definition +84,101,114,109,68,101,102,83,101,99,32,61,32,84,101,114,109,68,101,102,72,101, +97,100,101,114,46,105,103,110,111,114,101,40,41,32,43,32,126,68,101,102,105, +110,105,116,105,111,110,10, +// MatchersSec = MatchersHeader.ignore() + ~Matcher +77,97,116,99,104,101,114,115,83,101,99,32,61,32,77,97,116,99,104,101,114,115, +72,101,97,100,101,114,46,105,103,110,111,114,101,40,41,32,43,32,126,77,97,116, +99,104,101,114,10, +// +10, +// ModelDef = (RequestDefSec + TermDefSec + MatchersSec) ** flatten +77,111,100,101,108,68,101,102,32,61,32,40,82,101,113,117,101,115,116,68,101, +102,83,101,99,32,43,32,84,101,114,109,68,101,102,83,101,99,32,43,32,77,97,116, +99,104,101,114,115,83,101,99,41,32,42,42,32,102,108,97,116,116,101,110,10, +// +10, +// def preprocess(conf): +100,101,102,32,112,114,101,112,114,111,99,101,115,115,40,99,111,110,102,41,58, +10, +// # process escaped line breaks +32,32,32,32,35,32,112,114,111,99,101,115,115,32,101,115,99,97,112,101,100,32, +108,105,110,101,32,98,114,101,97,107,115,10, +// conf = conf.replace('\\\n', '') +32,32,32,32,99,111,110,102,32,61,32,99,111,110,102,46,114,101,112,108,97,99, +101,40,39,92,92,92,110,39,44,32,39,39,41,10, +// # remove comments +32,32,32,32,35,32,114,101,109,111,118,101,32,99,111,109,109,101,110,116,115, +32,32,32,32,10, +// conf = '\n'.join(line.partition('#')[0] for line in conf.splitlines()) +32,32,32,32,99,111,110,102,32,61,32,39,92,110,39,46,106,111,105,110,40,108,105, +110,101,46,112,97,114,116,105,116,105,111,110,40,39,35,39,41,91,48,93,32,102, +111,114,32,108,105,110,101,32,105,110,32,99,111,110,102,46,115,112,108,105,116, +108,105,110,101,115,40,41,41,10, +// # remove redundant new lines +32,32,32,32,35,32,114,101,109,111,118,101,32,114,101,100,117,110,100,97,110, +116,32,110,101,119,32,108,105,110,101,115,10, +// conf = conf.strip() +32,32,32,32,99,111,110,102,32,61,32,99,111,110,102,46,115,116,114,105,112,40, +41,10, +// +10, +// return conf + '\n' +32,32,32,32,114,101,116,117,114,110,32,99,111,110,102,32,43,32,39,92,110,39, +10, +// +10, +// def parse_model(text): +100,101,102,32,112,97,114,115,101,95,109,111,100,101,108,40,116,101,120,116, +41,58,10, +// text = preprocess(text) +32,32,32,32,116,101,120,116,32,61,32,112,114,101,112,114,111,99,101,115,115, +40,116,101,120,116,41,10, +// raw_model = ModelDef.parse_from(Stream(text)).payload +32,32,32,32,114,97,119,95,109,111,100,101,108,32,61,32,77,111,100,101,108,68, +101,102,46,112,97,114,115,101,95,102,114,111,109,40,83,116,114,101,97,109,40, +116,101,120,116,41,41,46,112,97,121,108,111,97,100,10, +// return raw_model +32,32,32,32,114,101,116,117,114,110,32,114,97,119,95,109,111,100,101,108,10, +// +10, +// class InvalidModelDefinition(Exception): +99,108,97,115,115,32,73,110,118,97,108,105,100,77,111,100,101,108,68,101,102, +105,110,105,116,105,111,110,40,69,120,99,101,112,116,105,111,110,41,58,10, +// def __init__(self, msg = ''): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,109,115,103,32,61,32,39,39,41,58,10, +// super(InvalidModelDefinition, self).__init__(msg) +32,32,32,32,32,32,32,32,115,117,112,101,114,40,73,110,118,97,108,105,100,77, +111,100,101,108,68,101,102,105,110,105,116,105,111,110,44,32,115,101,108,102, +41,46,95,95,105,110,105,116,95,95,40,109,115,103,41,32,32,32,32,32,32,32,32, +10, +// +10, +// @staticmethod +32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10, +// def redundant_def(redefined_vars, g1, g2): +32,32,32,32,100,101,102,32,114,101,100,117,110,100,97,110,116,95,100,101,102, +40,114,101,100,101,102,105,110,101,100,95,118,97,114,115,44,32,103,49,44,32, +103,50,41,58,10, +// msg_parts = [ +32,32,32,32,32,32,32,32,109,115,103,95,112,97,114,116,115,32,61,32,91,10, +// 'multiple definition(s) of identifiers(s)', +32,32,32,32,32,32,32,32,32,32,32,32,39,109,117,108,116,105,112,108,101,32,100, +101,102,105,110,105,116,105,111,110,40,115,41,32,111,102,32,105,100,101,110, +116,105,102,105,101,114,115,40,115,41,39,44,10, +// ', '.join(redfined_vars), +32,32,32,32,32,32,32,32,32,32,32,32,39,44,32,39,46,106,111,105,110,40,114,101, +100,102,105,110,101,100,95,118,97,114,115,41,44,10, +// 'found in sections', +32,32,32,32,32,32,32,32,32,32,32,32,39,102,111,117,110,100,32,105,110,32,115, +101,99,116,105,111,110,115,39,44,10, +// g1, g2 +32,32,32,32,32,32,32,32,32,32,32,32,103,49,44,32,103,50,10, +// ] +32,32,32,32,32,32,32,32,93,10, +// return InvalidModelDefinition(''.join(msg_parts)) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100, +77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,39,39,46,106,111, +105,110,40,109,115,103,95,112,97,114,116,115,41,41,10, +// +10, +// @staticmethod +32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10, +// def missing_matchers(missing_matchers): +32,32,32,32,100,101,102,32,109,105,115,115,105,110,103,95,109,97,116,99,104, +101,114,115,40,109,105,115,115,105,110,103,95,109,97,116,99,104,101,114,115, +41,58,10, +// msg = 'missing matcher(s) for request type(s): {}' +32,32,32,32,32,32,32,32,109,115,103,32,61,32,39,109,105,115,115,105,110,103, +32,109,97,116,99,104,101,114,40,115,41,32,102,111,114,32,114,101,113,117,101, +115,116,32,116,121,112,101,40,115,41,58,32,123,125,39,10, +// return InvalidModelDefinition(msg.format(', '.join(missing_matchers))) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100, +77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,109,115,103,46, +102,111,114,109,97,116,40,39,44,32,39,46,106,111,105,110,40,109,105,115,115, +105,110,103,95,109,97,116,99,104,101,114,115,41,41,41,10, +// +10, +// @staticmethod +32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10, +// def unknown_requests(unknown_requests): +32,32,32,32,100,101,102,32,117,110,107,110,111,119,110,95,114,101,113,117,101, +115,116,115,40,117,110,107,110,111,119,110,95,114,101,113,117,101,115,116,115, +41,58,10, +// msg = 'matcher(s) defined for unknown request type(s): {}' +32,32,32,32,32,32,32,32,109,115,103,32,61,32,39,109,97,116,99,104,101,114,40, +115,41,32,100,101,102,105,110,101,100,32,102,111,114,32,117,110,107,110,111, +119,110,32,114,101,113,117,101,115,116,32,116,121,112,101,40,115,41,58,32,123, +125,39,10, +// return InvalidModelDefinition(msg.format(', '.join(unknown_requests))) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100, +77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,109,115,103,46, +102,111,114,109,97,116,40,39,44,32,39,46,106,111,105,110,40,117,110,107,110, +111,119,110,95,114,101,113,117,101,115,116,115,41,41,41,10, +// +10, +// class Request(object): +99,108,97,115,115,32,82,101,113,117,101,115,116,40,111,98,106,101,99,116,41, +58,10, +// def __init__(self, attrs, vals): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,97,116,116,114,115,44,32,118,97,108,115,41,58,10, +// assert len(attrs) == len(vals) +32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,97,116,116, +114,115,41,32,61,61,32,108,101,110,40,118,97,108,115,41,10, +// self.__named_attrs = attrs +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,110,97,109,101,100,95,97,116, +116,114,115,32,61,32,97,116,116,114,115,10, +// for attr, val in zip(attrs, vals): +32,32,32,32,32,32,32,32,102,111,114,32,97,116,116,114,44,32,118,97,108,32,105, +110,32,122,105,112,40,97,116,116,114,115,44,32,118,97,108,115,41,58,10, +// setattr(self, attr, val) +32,32,32,32,32,32,32,32,32,32,32,32,115,101,116,97,116,116,114,40,115,101,108, +102,44,32,97,116,116,114,44,32,118,97,108,41,10, +// +10, +// def __repr__(self): +32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41, +58,10, +// parts = ['Request {\n'] +32,32,32,32,32,32,32,32,112,97,114,116,115,32,61,32,91,39,82,101,113,117,101, +115,116,32,123,92,110,39,93,10, +// for attr in self.__named_attrs: +32,32,32,32,32,32,32,32,102,111,114,32,97,116,116,114,32,105,110,32,115,101, +108,102,46,95,95,110,97,109,101,100,95,97,116,116,114,115,58,10, +// parts.append(' ') +32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110, +100,40,39,32,32,39,41,10, +// parts.append(attr) +32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110, +100,40,97,116,116,114,41,10, +// parts.append(': ') +32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110, +100,40,39,58,32,39,41,10, +// parts.append(repr(getattr(self, attr))) +32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110, +100,40,114,101,112,114,40,103,101,116,97,116,116,114,40,115,101,108,102,44,32, +97,116,116,114,41,41,41,10, +// parts.append('\n') +32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110, +100,40,39,92,110,39,41,10, +// parts.append('}\n') +32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,100,40,39,125, +92,110,39,41,10, +// return ''.join(parts) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110, +40,112,97,114,116,115,41,10, +// +10, +// class QueryResult(object): +99,108,97,115,115,32,81,117,101,114,121,82,101,115,117,108,116,40,111,98,106, +101,99,116,41,58,10, +// def __init__(self, generator): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,103,101,110,101,114,97,116,111,114,41,58,10, +// self.__gen = generator +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,103,101,110,32,61,32,103,101, +110,101,114,97,116,111,114,10, +// +10, +// def __iter__(self): +32,32,32,32,100,101,102,32,95,95,105,116,101,114,95,95,40,115,101,108,102,41, +58,10, +// return self.__gen +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95, +103,101,110,10, +// +10, +// def __le__(self, iterable): +32,32,32,32,100,101,102,32,95,95,108,101,95,95,40,115,101,108,102,44,32,105, +116,101,114,97,98,108,101,41,58,10, +// return set(self) <= set(iterable) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108, +102,41,32,60,61,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10, +// +10, +// def __lt__(self, iterable): +32,32,32,32,100,101,102,32,95,95,108,116,95,95,40,115,101,108,102,44,32,105, +116,101,114,97,98,108,101,41,58,10, +// return set(self) < set(iterable) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108, +102,41,32,60,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10, +// +10, +// def __ge__(self, iterable): +32,32,32,32,100,101,102,32,95,95,103,101,95,95,40,115,101,108,102,44,32,105, +116,101,114,97,98,108,101,41,58,10, +// return set(self) >= set(iterable) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108, +102,41,32,62,61,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10, +// +10, +// def __gt__(self, iterable): +32,32,32,32,100,101,102,32,95,95,103,116,95,95,40,115,101,108,102,44,32,105, +116,101,114,97,98,108,101,41,58,10, +// return set(self) > set(iterable) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108, +102,41,32,62,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10, +// +10, +// class Term(object): +99,108,97,115,115,32,84,101,114,109,40,111,98,106,101,99,116,41,58,10, +// PLACEHOLDER = object() +32,32,32,32,80,76,65,67,69,72,79,76,68,69,82,32,61,32,111,98,106,101,99,116, +40,41,10, +// WILDCARD = None +32,32,32,32,87,73,76,68,67,65,82,68,32,61,32,78,111,110,101,10, +// def __init__(self, arity): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,97,114,105,116,121,41,58,10, +// self.__arity = arity +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,97,114,105,116,121,32,61,32, +97,114,105,116,121,10, +// self.__facts = set() +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,97,99,116,115,32,61,32, +115,101,116,40,41,10, +// +10, +// def add_facts(self, facts): +32,32,32,32,100,101,102,32,97,100,100,95,102,97,99,116,115,40,115,101,108,102, +44,32,102,97,99,116,115,41,58,10, +// for fact in facts: +32,32,32,32,32,32,32,32,102,111,114,32,102,97,99,116,32,105,110,32,102,97,99, +116,115,58,10, +// self.add_fact(fact) +32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,97,100,100,95,102,97, +99,116,40,102,97,99,116,41,10, +// +10, +// def add_fact(self, fact): +32,32,32,32,100,101,102,32,97,100,100,95,102,97,99,116,40,115,101,108,102,44, +32,102,97,99,116,41,58,10, +// assert len(fact) == self.__arity +32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,102,97,99,116, +41,32,61,61,32,115,101,108,102,46,95,95,97,114,105,116,121,10, +// if not isinstance(fact, tuple): +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,105,115,105,110,115,116,97, +110,99,101,40,102,97,99,116,44,32,116,117,112,108,101,41,58,10, +// fact = tuple(fact) +32,32,32,32,32,32,32,32,32,32,32,32,102,97,99,116,32,61,32,116,117,112,108,101, +40,102,97,99,116,41,10, +// self.__facts.add(fact) +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,97,99,116,115,46,97,100, +100,40,102,97,99,116,41,10, +// +10, +// def __call__(self, *args): +32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32, +42,97,114,103,115,41,58,10, +// assert len(args) == self.__arity +32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,97,114,103, +115,41,32,61,61,32,115,101,108,102,46,95,95,97,114,105,116,121,10, +// # When all arguments are concrete, calling a term just returns boolean results +32,32,32,32,32,32,32,32,35,32,87,104,101,110,32,97,108,108,32,97,114,103,117, +109,101,110,116,115,32,97,114,101,32,99,111,110,99,114,101,116,101,44,32,99, +97,108,108,105,110,103,32,97,32,116,101,114,109,32,106,117,115,116,32,114,101, +116,117,114,110,115,32,98,111,111,108,101,97,110,32,114,101,115,117,108,116, +115,10, +// # indicating whether the called tuple is part of the known facts +32,32,32,32,32,32,32,32,35,32,105,110,100,105,99,97,116,105,110,103,32,119,104, +101,116,104,101,114,32,116,104,101,32,99,97,108,108,101,100,32,116,117,112,108, +101,32,105,115,32,112,97,114,116,32,111,102,32,116,104,101,32,107,110,111,119, +110,32,102,97,99,116,115,10, +// n_placeholders = sum(arg is Term.PLACEHOLDER for arg in args) +32,32,32,32,32,32,32,32,110,95,112,108,97,99,101,104,111,108,100,101,114,115, +32,61,32,115,117,109,40,97,114,103,32,105,115,32,84,101,114,109,46,80,76,65, +67,69,72,79,76,68,69,82,32,102,111,114,32,97,114,103,32,105,110,32,97,114,103, +115,41,10, +// if not n_placeholders: +32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,112,108,97,99,101,104, +111,108,100,101,114,115,58,10, +// return any(all(a == b for a, b in zip(fact, args)) for fact in self.__facts) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,97,110,121,40, +97,108,108,40,97,32,61,61,32,98,32,102,111,114,32,97,44,32,98,32,105,110,32, +122,105,112,40,102,97,99,116,44,32,97,114,103,115,41,41,32,102,111,114,32,102, +97,99,116,32,105,110,32,115,101,108,102,46,95,95,102,97,99,116,115,41,10, +// # If arguments contain one or more placeholders, calling a term is more like a +32,32,32,32,32,32,32,32,35,32,73,102,32,97,114,103,117,109,101,110,116,115,32, +99,111,110,116,97,105,110,32,111,110,101,32,111,114,32,109,111,114,101,32,112, +108,97,99,101,104,111,108,100,101,114,115,44,32,99,97,108,108,105,110,103,32, +97,32,116,101,114,109,32,105,115,32,109,111,114,101,32,108,105,107,101,32,97, +10, +// # query. The call returns a generator that iterates all facts that match with +32,32,32,32,32,32,32,32,35,32,113,117,101,114,121,46,32,84,104,101,32,99,97, +108,108,32,114,101,116,117,114,110,115,32,97,32,103,101,110,101,114,97,116,111, +114,32,116,104,97,116,32,105,116,101,114,97,116,101,115,32,97,108,108,32,102, +97,99,116,115,32,116,104,97,116,32,109,97,116,99,104,32,119,105,116,104,10, +// # the pattern described by the arguments +32,32,32,32,32,32,32,32,35,32,116,104,101,32,112,97,116,116,101,114,110,32,100, +101,115,99,114,105,98,101,100,32,98,121,32,116,104,101,32,97,114,103,117,109, +101,110,116,115,10, +// def gen(): +32,32,32,32,32,32,32,32,100,101,102,32,103,101,110,40,41,58,10, +// for fact in self.__facts: +32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,102,97,99,116,32,105,110, +32,115,101,108,102,46,95,95,102,97,99,116,115,58,10, +// rns = [] +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114,110,115,32,61,32,91,93,10, +// matched = True +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,109,97,116,99,104,101,100,32, +61,32,84,114,117,101,10, +// for a, b in zip(fact, args): +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,97,44,32,98,32, +105,110,32,122,105,112,40,102,97,99,116,44,32,97,114,103,115,41,58,10, +// if b is Term.PLACEHOLDER: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,98,32, +105,115,32,84,101,114,109,46,80,76,65,67,69,72,79,76,68,69,82,58,10, +// rns.append(a) +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114, +110,115,46,97,112,112,101,110,100,40,97,41,10, +// else: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101,108,115,101, +58,10, +// if a != b: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105, +102,32,97,32,33,61,32,98,58,10, +// matched = False +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,109,97,116,99,104,101,100,32,61,32,70,97,108,115,101,10, +// break +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,98,114,101,97,107,10, +// if matched: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,109,97,116,99,104, +101,100,58,10, +// if n_placeholders == 1: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,110,95, +112,108,97,99,101,104,111,108,100,101,114,115,32,61,61,32,49,58,10, +// yield rns[0] +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,121, +105,101,108,100,32,114,110,115,91,48,93,10, +// else: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101,108,115,101, +58,10, +// yield tuple(rns) +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,121, +105,101,108,100,32,116,117,112,108,101,40,114,110,115,41,10, +// return QueryResult(gen()) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,81,117,101,114,121,82,101, +115,117,108,116,40,103,101,110,40,41,41,10, +// +10, +// class Model(object): +99,108,97,115,115,32,77,111,100,101,108,40,111,98,106,101,99,116,41,58,10, +// def __init__(self, raw_model): +32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44, +32,114,97,119,95,109,111,100,101,108,41,58,10, +// request_def, term_def, matchers = raw_model +32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,100,101,102,44,32,116, +101,114,109,95,100,101,102,44,32,109,97,116,99,104,101,114,115,32,61,32,114, +97,119,95,109,111,100,101,108,10, +// self.__request_template = { r[0]:r[1] for r in request_def } +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,114,101,113,117,101,115,116, +95,116,101,109,112,108,97,116,101,32,61,32,123,32,114,91,48,93,58,114,91,49, +93,32,102,111,114,32,114,32,105,110,32,114,101,113,117,101,115,116,95,100,101, +102,32,125,10, +// self.__term_template = { t[0]:t[1] for t in term_def } +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,101,114,109,95,116,101, +109,112,108,97,116,101,32,61,32,123,32,116,91,48,93,58,116,91,49,93,32,102,111, +114,32,116,32,105,110,32,116,101,114,109,95,100,101,102,32,125,10, +// self.__matchers = { m[0]:m[1] for m in matchers } +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115, +32,61,32,123,32,109,91,48,93,58,109,91,49,93,32,102,111,114,32,109,32,105,110, +32,109,97,116,99,104,101,114,115,32,125,10, +// +10, +// def_sections = zip( +32,32,32,32,32,32,32,32,100,101,102,95,115,101,99,116,105,111,110,115,32,61, +32,122,105,112,40,10, +// ['[requests]', '[terms]'], +32,32,32,32,32,32,32,32,32,32,32,32,91,39,91,114,101,113,117,101,115,116,115, +93,39,44,32,39,91,116,101,114,109,115,93,39,93,44,10, +// [self.__request_template, self.__term_template], +32,32,32,32,32,32,32,32,32,32,32,32,91,115,101,108,102,46,95,95,114,101,113, +117,101,115,116,95,116,101,109,112,108,97,116,101,44,32,115,101,108,102,46,95, +95,116,101,114,109,95,116,101,109,112,108,97,116,101,93,44,10, +// ) +32,32,32,32,32,32,32,32,41,10, +// +10, +// n_sec = len(def_sections) +32,32,32,32,32,32,32,32,110,95,115,101,99,32,61,32,108,101,110,40,100,101,102, +95,115,101,99,116,105,111,110,115,41,10, +// for i in range(n_sec): +32,32,32,32,32,32,32,32,102,111,114,32,105,32,105,110,32,114,97,110,103,101, +40,110,95,115,101,99,41,58,10, +// for j in range(i + 1, n_sec): +32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,106,32,105,110,32,114,97, +110,103,101,40,105,32,43,32,49,44,32,110,95,115,101,99,41,58,10, +// overlap = set(def_sections[i][1].keys()) & set(def_sections[j][1].keys()) +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,111,118,101,114,108,97,112,32, +61,32,115,101,116,40,100,101,102,95,115,101,99,116,105,111,110,115,91,105,93, +91,49,93,46,107,101,121,115,40,41,41,32,38,32,115,101,116,40,100,101,102,95, +115,101,99,116,105,111,110,115,91,106,93,91,49,93,46,107,101,121,115,40,41,41, +10, +// if overlap: +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,111,118,101,114,108, +97,112,58,10, +// raise InvalidModelDefinition.redundant_def( +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101, +32,73,110,118,97,108,105,100,77,111,100,101,108,68,101,102,105,110,105,116,105, +111,110,46,114,101,100,117,110,100,97,110,116,95,100,101,102,40,10, +// overalp, def_sections[i][0], def_sections[j][0] +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,111, +118,101,114,97,108,112,44,32,100,101,102,95,115,101,99,116,105,111,110,115,91, +105,93,91,48,93,44,32,100,101,102,95,115,101,99,116,105,111,110,115,91,106,93, +91,48,93,10, +// ) +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,41,10, +// +10, +// missing_matchers = set(self.__request_template.keys()) - set(self.__matchers.keys()) +32,32,32,32,32,32,32,32,109,105,115,115,105,110,103,95,109,97,116,99,104,101, +114,115,32,61,32,115,101,116,40,115,101,108,102,46,95,95,114,101,113,117,101, +115,116,95,116,101,109,112,108,97,116,101,46,107,101,121,115,40,41,41,32,45, +32,115,101,116,40,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115,46, +107,101,121,115,40,41,41,10, +// if missing_matchers: +32,32,32,32,32,32,32,32,105,102,32,109,105,115,115,105,110,103,95,109,97,116, +99,104,101,114,115,58,10, +// raise InvalidModelDefinition.missing_matchers(missing_matchers) +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,73,110,118,97,108, +105,100,77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,46,109,105, +115,115,105,110,103,95,109,97,116,99,104,101,114,115,40,109,105,115,115,105, +110,103,95,109,97,116,99,104,101,114,115,41,10, +// +10, +// unknown_requests = set(self.__matchers.keys()) - set(self.__request_template.keys()) +32,32,32,32,32,32,32,32,117,110,107,110,111,119,110,95,114,101,113,117,101,115, +116,115,32,61,32,115,101,116,40,115,101,108,102,46,95,95,109,97,116,99,104,101, +114,115,46,107,101,121,115,40,41,41,32,45,32,115,101,116,40,115,101,108,102, +46,95,95,114,101,113,117,101,115,116,95,116,101,109,112,108,97,116,101,46,107, +101,121,115,40,41,41,10, +// if unknown_requests: +32,32,32,32,32,32,32,32,105,102,32,117,110,107,110,111,119,110,95,114,101,113, +117,101,115,116,115,58,10, +// raise InvalidModelDefinition.unknown_requests(unknown_requests) +32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,73,110,118,97,108, +105,100,77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,46,117,110, +107,110,111,119,110,95,114,101,113,117,101,115,116,115,40,117,110,107,110,111, +119,110,95,114,101,113,117,101,115,116,115,41,10, +// +10, +// self.__term_knowledge_base = { +32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,101,114,109,95,107,110, +111,119,108,101,100,103,101,95,98,97,115,101,32,61,32,123,10, +// term_name:Term(len(term_tpl)) for term_name, term_tpl in self.__term_template.items() +32,32,32,32,32,32,32,32,32,32,32,32,116,101,114,109,95,110,97,109,101,58,84, +101,114,109,40,108,101,110,40,116,101,114,109,95,116,112,108,41,41,32,102,111, +114,32,116,101,114,109,95,110,97,109,101,44,32,116,101,114,109,95,116,112,108, +32,105,110,32,115,101,108,102,46,95,95,116,101,114,109,95,116,101,109,112,108, +97,116,101,46,105,116,101,109,115,40,41,10, +// } +32,32,32,32,32,32,32,32,125,10, +// +10, +// def add_term_items(self, term_items): +32,32,32,32,100,101,102,32,97,100,100,95,116,101,114,109,95,105,116,101,109, +115,40,115,101,108,102,44,32,116,101,114,109,95,105,116,101,109,115,41,58,10, +// for ti in term_items: +32,32,32,32,32,32,32,32,102,111,114,32,116,105,32,105,110,32,116,101,114,109, +95,105,116,101,109,115,58,10, +// self.add_term_item(ti[0], ti[1:]) +32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,97,100,100,95,116,101, +114,109,95,105,116,101,109,40,116,105,91,48,93,44,32,116,105,91,49,58,93,41, +10, +// +10, +// def add_term_item(self, term_name, fact): +32,32,32,32,100,101,102,32,97,100,100,95,116,101,114,109,95,105,116,101,109, +40,115,101,108,102,44,32,116,101,114,109,95,110,97,109,101,44,32,102,97,99,116, +41,58,10, +// term = self.__term_knowledge_base[term_name] +32,32,32,32,32,32,32,32,116,101,114,109,32,61,32,115,101,108,102,46,95,95,116, +101,114,109,95,107,110,111,119,108,101,100,103,101,95,98,97,115,101,91,116,101, +114,109,95,110,97,109,101,93,10, +// term.add_fact(fact) +32,32,32,32,32,32,32,32,116,101,114,109,46,97,100,100,95,102,97,99,116,40,102, +97,99,116,41,10, +// +10, +// def get_matcher_proxy(self, request_type, env): +32,32,32,32,100,101,102,32,103,101,116,95,109,97,116,99,104,101,114,95,112,114, +111,120,121,40,115,101,108,102,44,32,114,101,113,117,101,115,116,95,116,121, +112,101,44,32,101,110,118,41,58,10, +// def matcher_proxy(): +32,32,32,32,32,32,32,32,100,101,102,32,109,97,116,99,104,101,114,95,112,114, +111,120,121,40,41,58,10, +// return eval(self.__matchers[request_type], env) +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,101,118,97,108, +40,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115,91,114,101,113,117, +101,115,116,95,116,121,112,101,93,44,32,101,110,118,41,10, +// return matcher_proxy +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,109,97,116,99,104,101,114, +95,112,114,111,120,121,10, +// +10, +// def enforce(self, request_type, request_content): +32,32,32,32,100,101,102,32,101,110,102,111,114,99,101,40,115,101,108,102,44, +32,114,101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113,117,101, +115,116,95,99,111,110,116,101,110,116,41,58,10, +// tpl = self.__request_template[request_type] +32,32,32,32,32,32,32,32,116,112,108,32,61,32,115,101,108,102,46,95,95,114,101, +113,117,101,115,116,95,116,101,109,112,108,97,116,101,91,114,101,113,117,101, +115,116,95,116,121,112,101,93,10, +// request = Request(tpl, request_content) +32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,32,61,32,82,101,113,117, +101,115,116,40,116,112,108,44,32,114,101,113,117,101,115,116,95,99,111,110,116, +101,110,116,41,10, +// +10, +// enforcer_env = { +32,32,32,32,32,32,32,32,101,110,102,111,114,99,101,114,95,101,110,118,32,61, +32,123,10, +// request_type: request, +32,32,32,32,32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,116,121,112, +101,58,32,114,101,113,117,101,115,116,44,10, +// 'true': True, 'false': False, 'null': None, +32,32,32,32,32,32,32,32,32,32,32,32,39,116,114,117,101,39,58,32,84,114,117,101, +44,32,39,102,97,108,115,101,39,58,32,70,97,108,115,101,44,32,39,110,117,108, +108,39,58,32,78,111,110,101,44,10, +// '_': Term.PLACEHOLDER, +32,32,32,32,32,32,32,32,32,32,32,32,39,95,39,58,32,84,101,114,109,46,80,76,65, +67,69,72,79,76,68,69,82,44,10, +// 'X': Term.WILDCARD, +32,32,32,32,32,32,32,32,32,32,32,32,39,88,39,58,32,84,101,114,109,46,87,73,76, +68,67,65,82,68,44,10, +// } +32,32,32,32,32,32,32,32,125,10, +// enforcer_env.update(self.__term_knowledge_base) +32,32,32,32,32,32,32,32,101,110,102,111,114,99,101,114,95,101,110,118,46,117, +112,100,97,116,101,40,115,101,108,102,46,95,95,116,101,114,109,95,107,110,111, +119,108,101,100,103,101,95,98,97,115,101,41,10, +// +10, +// return eval(self.__matchers[request_type], enforcer_env) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,101,118,97,108,40,115,101, +108,102,46,95,95,109,97,116,99,104,101,114,115,91,114,101,113,117,101,115,116, +95,116,121,112,101,93,44,32,101,110,102,111,114,99,101,114,95,101,110,118,41, +10, +// +10, +// global_perm_model = None +103,108,111,98,97,108,95,112,101,114,109,95,109,111,100,101,108,32,61,32,78, +111,110,101,10, +// +10, +// if __name__ == '__builtin__': +105,102,32,95,95,110,97,109,101,95,95,32,61,61,32,39,95,95,98,117,105,108,116, +105,110,95,95,39,58,10, +// from acs_py_enclave import ffi +32,32,32,32,102,114,111,109,32,97,99,115,95,112,121,95,101,110,99,108,97,118, +101,32,105,109,112,111,114,116,32,102,102,105,10, +// else: +101,108,115,101,58,10, +// class ffi: +32,32,32,32,99,108,97,115,115,32,102,102,105,58,10, +// @staticmethod +32,32,32,32,32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10, +// def def_extern(): +32,32,32,32,32,32,32,32,100,101,102,32,100,101,102,95,101,120,116,101,114,110, +40,41,58,10, +// return lambda x: x +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,108,97,109,98, +100,97,32,120,58,32,120,10, +// +10, +// @staticmethod +32,32,32,32,32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10, +// def string(s): +32,32,32,32,32,32,32,32,100,101,102,32,115,116,114,105,110,103,40,115,41,58, +10, +// return s +32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,10, +// +10, +// @ffi.def_extern() +64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10, +// def acs_setup_model(conf): +100,101,102,32,97,99,115,95,115,101,116,117,112,95,109,111,100,101,108,40,99, +111,110,102,41,58,10, +// try: +32,32,32,32,116,114,121,58,10, +// global global_perm_model +32,32,32,32,32,32,32,32,103,108,111,98,97,108,32,103,108,111,98,97,108,95,112, +101,114,109,95,109,111,100,101,108,10, +// conf = ffi.string(conf) +32,32,32,32,32,32,32,32,99,111,110,102,32,61,32,102,102,105,46,115,116,114,105, +110,103,40,99,111,110,102,41,10, +// global_perm_model = Model(parse_model(conf)) +32,32,32,32,32,32,32,32,103,108,111,98,97,108,95,112,101,114,109,95,109,111, +100,101,108,32,61,32,77,111,100,101,108,40,112,97,114,115,101,95,109,111,100, +101,108,40,99,111,110,102,41,41,10, +// except: +32,32,32,32,101,120,99,101,112,116,58,10, +// return -1 +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10, +// return 0 +32,32,32,32,114,101,116,117,114,110,32,48,10, +// +10, +// @ffi.def_extern() +64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10, +// def acs_enforce_request(request_type, request_content): +100,101,102,32,97,99,115,95,101,110,102,111,114,99,101,95,114,101,113,117,101, +115,116,40,114,101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113, +117,101,115,116,95,99,111,110,116,101,110,116,41,58,10, +// try: +32,32,32,32,116,114,121,58,10, +// request_type = ffi.string(request_type) +32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,116,121,112,101,32,61, +32,102,102,105,46,115,116,114,105,110,103,40,114,101,113,117,101,115,116,95, +116,121,112,101,41,10, +// # request_content is a list of ffi c strings which are syntactically valid +32,32,32,32,32,32,32,32,35,32,114,101,113,117,101,115,116,95,99,111,110,116, +101,110,116,32,105,115,32,97,32,108,105,115,116,32,111,102,32,102,102,105,32, +99,32,115,116,114,105,110,103,115,32,119,104,105,99,104,32,97,114,101,32,115, +121,110,116,97,99,116,105,99,97,108,108,121,32,118,97,108,105,100,10, +// # python primitive-type objects, including strings, integers, foating point +32,32,32,32,32,32,32,32,35,32,112,121,116,104,111,110,32,112,114,105,109,105, +116,105,118,101,45,116,121,112,101,32,111,98,106,101,99,116,115,44,32,105,110, +99,108,117,100,105,110,103,32,115,116,114,105,110,103,115,44,32,105,110,116, +101,103,101,114,115,44,32,102,111,97,116,105,110,103,32,112,111,105,110,116, +10, +// # numbers, and lists/dictionaries of primitive-type objects +32,32,32,32,32,32,32,32,35,32,110,117,109,98,101,114,115,44,32,97,110,100,32, +108,105,115,116,115,47,100,105,99,116,105,111,110,97,114,105,101,115,32,111, +102,32,112,114,105,109,105,116,105,118,101,45,116,121,112,101,32,111,98,106, +101,99,116,115,10, +// request_content = eval(ffi.string(request_content)) +32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,99,111,110,116,101,110, +116,32,61,32,101,118,97,108,40,102,102,105,46,115,116,114,105,110,103,40,114, +101,113,117,101,115,116,95,99,111,110,116,101,110,116,41,41,10, +// return global_perm_model.enforce(request_type, request_content) +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,103,108,111,98,97,108,95, +112,101,114,109,95,109,111,100,101,108,46,101,110,102,111,114,99,101,40,114, +101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113,117,101,115,116, +95,99,111,110,116,101,110,116,41,10, +// except: +32,32,32,32,101,120,99,101,112,116,58,10, +// return -1 +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10, +// +10, +// @ffi.def_extern() +64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10, +// def acs_announce_fact(term_type, term_fact): +100,101,102,32,97,99,115,95,97,110,110,111,117,110,99,101,95,102,97,99,116,40, +116,101,114,109,95,116,121,112,101,44,32,116,101,114,109,95,102,97,99,116,41, +58,10, +// try: +32,32,32,32,116,114,121,58,10, +// term_type = ffi.string(term_type) +32,32,32,32,32,32,32,32,116,101,114,109,95,116,121,112,101,32,61,32,102,102, +105,46,115,116,114,105,110,103,40,116,101,114,109,95,116,121,112,101,41,10, +// term_fact = eval(ffi.string(term_fact)) +32,32,32,32,32,32,32,32,116,101,114,109,95,102,97,99,116,32,61,32,101,118,97, +108,40,102,102,105,46,115,116,114,105,110,103,40,116,101,114,109,95,102,97,99, +116,41,41,10, +// global_perm_model.add_term_item(term_type, term_fact) +32,32,32,32,32,32,32,32,103,108,111,98,97,108,95,112,101,114,109,95,109,111, +100,101,108,46,97,100,100,95,116,101,114,109,95,105,116,101,109,40,116,101,114, +109,95,116,121,112,101,44,32,116,101,114,109,95,102,97,99,116,41,10, +// except: +32,32,32,32,101,120,99,101,112,116,58,10, +// return -1 +32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10, +// return 0 +32,32,32,32,114,101,116,117,114,110,32,48,10, +0 }; +#ifdef PYPY_VERSION +# define _CFFI_PYTHON_STARTUP_FUNC _cffi_pypyinit_acs_py_enclave +#elif PY_MAJOR_VERSION >= 3 +# define _CFFI_PYTHON_STARTUP_FUNC PyInit_acs_py_enclave +#else +# define _CFFI_PYTHON_STARTUP_FUNC initacs_py_enclave +#endif + +/***** Support code for embedding *****/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(_WIN32) +# define CFFI_DLLEXPORT __declspec(dllexport) +#elif defined(__GNUC__) +# define CFFI_DLLEXPORT __attribute__((visibility("default"))) +#else +# define CFFI_DLLEXPORT /* nothing */ +#endif + + +/* There are two global variables of type _cffi_call_python_fnptr: + + * _cffi_call_python, which we declare just below, is the one called + by ``extern "Python"`` implementations. + + * _cffi_call_python_org, which on CPython is actually part of the + _cffi_exports[] array, is the function pointer copied from + _cffi_backend. + + After initialization is complete, both are equal. However, the + first one remains equal to &_cffi_start_and_call_python until the + very end of initialization, when we are (or should be) sure that + concurrent threads also see a completely initialized world, and + only then is it changed. +*/ +#undef _cffi_call_python +typedef void (*_cffi_call_python_fnptr)(struct _cffi_externpy_s *, char *); +static void _cffi_start_and_call_python(struct _cffi_externpy_s *, char *); +static _cffi_call_python_fnptr _cffi_call_python = &_cffi_start_and_call_python; + + +#ifndef _MSC_VER + /* --- Assuming a GCC not infinitely old --- */ +# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) +# define cffi_write_barrier() __sync_synchronize() +# if !defined(__amd64__) && !defined(__x86_64__) && \ + !defined(__i386__) && !defined(__i386) +# define cffi_read_barrier() __sync_synchronize() +# else +# define cffi_read_barrier() (void)0 +# endif +#else + /* --- Windows threads version --- */ +# include <Windows.h> +# define cffi_compare_and_swap(l,o,n) \ + (InterlockedCompareExchangePointer(l,n,o) == (o)) +# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_read_barrier() (void)0 +static volatile LONG _cffi_dummy; +#endif + +#ifdef WITH_THREAD +# ifndef _MSC_VER +# include <pthread.h> + static pthread_mutex_t _cffi_embed_startup_lock; +# else + static CRITICAL_SECTION _cffi_embed_startup_lock; +# endif + static char _cffi_embed_startup_lock_ready = 0; +#endif + +static void _cffi_acquire_reentrant_mutex(void) +{ + static void *volatile lock = NULL; + + while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) { + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: pthread_mutex_init() should be very fast, and + this is only run at start-up anyway. */ + } + +#ifdef WITH_THREAD + if (!_cffi_embed_startup_lock_ready) { +# ifndef _MSC_VER + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_cffi_embed_startup_lock, &attr); +# else + InitializeCriticalSection(&_cffi_embed_startup_lock); +# endif + _cffi_embed_startup_lock_ready = 1; + } +#endif + + while (!cffi_compare_and_swap(&lock, (void *)1, NULL)) + ; + +#ifndef _MSC_VER + pthread_mutex_lock(&_cffi_embed_startup_lock); +#else + EnterCriticalSection(&_cffi_embed_startup_lock); +#endif +} + +static void _cffi_release_reentrant_mutex(void) +{ +#ifndef _MSC_VER + pthread_mutex_unlock(&_cffi_embed_startup_lock); +#else + LeaveCriticalSection(&_cffi_embed_startup_lock); +#endif +} + + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + +#ifndef CFFI_MESSAGEBOX +# ifdef _MSC_VER +# define CFFI_MESSAGEBOX 1 +# else +# define CFFI_MESSAGEBOX 0 +# endif +#endif + + +#if CFFI_MESSAGEBOX +/* Windows only: logic to take the Python-CFFI embedding logic + initialization errors and display them in a background thread + with MessageBox. The idea is that if the whole program closes + as a result of this problem, then likely it is already a console + program and you can read the stderr output in the console too. + If it is not a console program, then it will likely show its own + dialog to complain, or generally not abruptly close, and for this + case the background thread should stay alive. +*/ +static void *volatile _cffi_bootstrap_text; + +static PyObject *_cffi_start_error_capture(void) +{ + PyObject *result = NULL; + PyObject *x, *m, *bi; + + if (InterlockedCompareExchangePointer(&_cffi_bootstrap_text, + (void *)1, NULL) != NULL) + return (PyObject *)1; + + m = PyImport_AddModule("_cffi_error_capture"); + if (m == NULL) + goto error; + + result = PyModule_GetDict(m); + if (result == NULL) + goto error; + +#if PY_MAJOR_VERSION >= 3 + bi = PyImport_ImportModule("builtins"); +#else + bi = PyImport_ImportModule("__builtin__"); +#endif + if (bi == NULL) + goto error; + PyDict_SetItemString(result, "__builtins__", bi); + Py_DECREF(bi); + + x = PyRun_String( + "import sys\n" + "class FileLike:\n" + " def write(self, x):\n" + " of.write(x)\n" + " self.buf += x\n" + "fl = FileLike()\n" + "fl.buf = ''\n" + "of = sys.stderr\n" + "sys.stderr = fl\n" + "def done():\n" + " sys.stderr = of\n" + " return fl.buf\n", /* make sure the returned value stays alive */ + Py_file_input, + result, result); + Py_XDECREF(x); + + error: + if (PyErr_Occurred()) + { + PyErr_WriteUnraisable(Py_None); + PyErr_Clear(); + } + return result; +} + +#pragma comment(lib, "user32.lib") + +static DWORD WINAPI _cffi_bootstrap_dialog(LPVOID ignored) +{ + Sleep(666); /* may be interrupted if the whole process is closing */ +#if PY_MAJOR_VERSION >= 3 + MessageBoxW(NULL, (wchar_t *)_cffi_bootstrap_text, + L"Python-CFFI error", + MB_OK | MB_ICONERROR); +#else + MessageBoxA(NULL, (char *)_cffi_bootstrap_text, + "Python-CFFI error", + MB_OK | MB_ICONERROR); +#endif + _cffi_bootstrap_text = NULL; + return 0; +} + +static void _cffi_stop_error_capture(PyObject *ecap) +{ + PyObject *s; + void *text; + + if (ecap == (PyObject *)1) + return; + + if (ecap == NULL) + goto error; + + s = PyRun_String("done()", Py_eval_input, ecap, ecap); + if (s == NULL) + goto error; + + /* Show a dialog box, but in a background thread, and + never show multiple dialog boxes at once. */ +#if PY_MAJOR_VERSION >= 3 + text = PyUnicode_AsWideCharString(s, NULL); +#else + text = PyString_AsString(s); +#endif + + _cffi_bootstrap_text = text; + + if (text != NULL) + { + HANDLE h; + h = CreateThread(NULL, 0, _cffi_bootstrap_dialog, + NULL, 0, NULL); + if (h != NULL) + CloseHandle(h); + } + /* decref the string, but it should stay alive as 'fl.buf' + in the small module above. It will really be freed only if + we later get another similar error. So it's a leak of at + most one copy of the small module. That's fine for this + situation which is usually a "fatal error" anyway. */ + Py_DECREF(s); + PyErr_Clear(); + return; + + error: + _cffi_bootstrap_text = NULL; + PyErr_Clear(); +} + +#else + +static PyObject *_cffi_start_error_capture(void) { return NULL; } +static void _cffi_stop_error_capture(PyObject *ecap) { } + +#endif + + +#define _cffi_call_python_org _cffi_exports[_CFFI_CPIDX] + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(void); /* forward */ + +static void _cffi_py_initialize(void) +{ + /* XXX use initsigs=0, which "skips initialization registration of + signal handlers, which might be useful when Python is + embedded" according to the Python docs. But review and think + if it should be a user-controllable setting. + + XXX we should also give a way to write errors to a buffer + instead of to stderr. + + XXX if importing 'site' fails, CPython (any version) calls + exit(). Should we try to work around this behavior here? + */ + Py_InitializeEx(0); +} + +static int _cffi_initialize_python(void) +{ + /* This initializes Python, imports _cffi_backend, and then the + present .dll/.so is set up as a CPython C extension module. + */ + int result; + PyGILState_STATE state; + PyObject *pycode=NULL, *global_dict=NULL, *x; + + state = PyGILState_Ensure(); + + /* Call the initxxx() function from the present module. It will + create and initialize us as a CPython extension module, instead + of letting the startup Python code do it---it might reimport + the same .dll/.so and get maybe confused on some platforms. + It might also have troubles locating the .dll/.so again for all + I know. + */ + (void)_CFFI_PYTHON_STARTUP_FUNC(); + if (PyErr_Occurred()) + goto error; + + /* Now run the Python code provided to ffi.embedding_init_code(). + */ + pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE, + "<init code for '" _CFFI_MODULE_NAME "'>", + Py_file_input); + if (pycode == NULL) + goto error; + global_dict = PyDict_New(); + if (global_dict == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", + PyThreadState_GET()->interp->builtins) < 0) + goto error; + x = PyEval_EvalCode( +#if PY_MAJOR_VERSION < 3 + (PyCodeObject *) +#endif + pycode, global_dict, global_dict); + if (x == NULL) + goto error; + Py_DECREF(x); + + /* Done! Now if we've been called from + _cffi_start_and_call_python() in an ``extern "Python"``, we can + only hope that the Python code did correctly set up the + corresponding @ffi.def_extern() function. Otherwise, the + general logic of ``extern "Python"`` functions (inside the + _cffi_backend module) will find that the reference is still + missing and print an error. + */ + result = 0; + done: + Py_XDECREF(pycode); + Py_XDECREF(global_dict); + PyGILState_Release(state); + return result; + + error:; + { + /* Print as much information as potentially useful. + Debugging load-time failures with embedding is not fun + */ + PyObject *ecap; + PyObject *exception, *v, *tb, *f, *modules, *mod; + PyErr_Fetch(&exception, &v, &tb); + ecap = _cffi_start_error_capture(); + f = PySys_GetObject((char *)"stderr"); + if (f != NULL && f != Py_None) { + PyFile_WriteString( + "Failed to initialize the Python-CFFI embedding logic:\n\n", f); + } + + if (exception != NULL) { + PyErr_NormalizeException(&exception, &v, &tb); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); + + if (f != NULL && f != Py_None) { + PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME + "\ncompiled with cffi version: 1.11.5" + "\n_cffi_backend module: ", f); + modules = PyImport_GetModuleDict(); + mod = PyDict_GetItemString(modules, "_cffi_backend"); + if (mod == NULL) { + PyFile_WriteString("not loaded", f); + } + else { + v = PyObject_GetAttrString(mod, "__file__"); + PyFile_WriteObject(v, f, 0); + Py_XDECREF(v); + } + PyFile_WriteString("\nsys.path: ", f); + PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0); + PyFile_WriteString("\n\n", f); + } + _cffi_stop_error_capture(ecap); + } + result = -1; + goto done; +} + +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ + +static int _cffi_carefully_make_gil(void) +{ + /* This does the basic initialization of Python. It can be called + completely concurrently from unrelated threads. It assumes + that we don't hold the GIL before (if it exists), and we don't + hold it afterwards. + + (What it really does used to be completely different in Python 2 + and Python 3, with the Python 2 solution avoiding the spin-lock + around the Py_InitializeEx() call. However, after recent changes + to CPython 2.7 (issue #358) it no longer works. So we use the + Python 3 solution everywhere.) + + This initializes Python by calling Py_InitializeEx(). + Important: this must not be called concurrently at all. + So we use a global variable as a simple spin lock. This global + variable must be from 'libpythonX.Y.so', not from this + cffi-based extension module, because it must be shared from + different cffi-based extension modules. We choose + _PyParser_TokenNames[0] as a completely arbitrary pointer value + that is never written to. The default is to point to the + string "ENDMARKER". We change it temporarily to point to the + next character in that string. (Yes, I know it's REALLY + obscure.) + */ + +#ifdef WITH_THREAD + char *volatile *lock = (char *volatile *)_PyParser_TokenNames; + char *old_value; + + while (1) { /* spin loop */ + old_value = *lock; + if (old_value[0] == 'E') { + assert(old_value[1] == 'N'); + if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + break; + } + else { + assert(old_value[0] == 'N'); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +#endif + + /* call Py_InitializeEx() */ + { + PyGILState_STATE state = PyGILState_UNLOCKED; + if (!Py_IsInitialized()) + _cffi_py_initialize(); + else + state = PyGILState_Ensure(); + + PyEval_InitThreads(); + PyGILState_Release(state); + } + +#ifdef WITH_THREAD + /* release the lock */ + while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + ; +#endif + + return 0; +} + +/********** end CPython-specific section **********/ + + +#else + + +/********** PyPy-specific section **********/ + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]); /* forward */ + +static struct _cffi_pypy_init_s { + const char *name; + void (*func)(const void *[]); + const char *code; +} _cffi_pypy_init = { + _CFFI_MODULE_NAME, + (void(*)(const void *[]))_CFFI_PYTHON_STARTUP_FUNC, + _CFFI_PYTHON_STARTUP_CODE, +}; + +extern int pypy_carefully_make_gil(const char *); +extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *); + +static int _cffi_carefully_make_gil(void) +{ + return pypy_carefully_make_gil(_CFFI_MODULE_NAME); +} + +static int _cffi_initialize_python(void) +{ + return pypy_init_embedded_cffi_module(0xB011, &_cffi_pypy_init); +} + +/********** end PyPy-specific section **********/ + + +#endif + + +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +static _cffi_call_python_fnptr _cffi_start_python(void) +{ + /* Delicate logic to initialize Python. This function can be + called multiple times concurrently, e.g. when the process calls + its first ``extern "Python"`` functions in multiple threads at + once. It can also be called recursively, in which case we must + ignore it. We also have to consider what occurs if several + different cffi-based extensions reach this code in parallel + threads---it is a different copy of the code, then, and we + can't have any shared global variable unless it comes from + 'libpythonX.Y.so'. + + Idea: + + * _cffi_carefully_make_gil(): "carefully" call + PyEval_InitThreads() (possibly with Py_InitializeEx() first). + + * then we use a (local) custom lock to make sure that a call to this + cffi-based extension will wait if another call to the *same* + extension is running the initialization in another thread. + It is reentrant, so that a recursive call will not block, but + only one from a different thread. + + * then we grab the GIL and (Python 2) we call Py_InitializeEx(). + At this point, concurrent calls to Py_InitializeEx() are not + possible: we have the GIL. + + * do the rest of the specific initialization, which may + temporarily release the GIL but not the custom lock. + Only release the custom lock when we are done. + */ + static char called = 0; + + if (_cffi_carefully_make_gil() != 0) + return NULL; + +#ifndef SGX + _cffi_acquire_reentrant_mutex(); +#endif + + /* Here the GIL exists, but we don't have it. We're only protected + from concurrency by the reentrant mutex. */ + + /* This file only initializes the embedded module once, the first + time this is called, even if there are subinterpreters. */ + if (!called) { + called = 1; /* invoke _cffi_initialize_python() only once, + but don't set '_cffi_call_python' right now, + otherwise concurrent threads won't call + this function at all (we need them to wait) */ + if (_cffi_initialize_python() == 0) { + /* now initialization is finished. Switch to the fast-path. */ + + /* We would like nobody to see the new value of + '_cffi_call_python' without also seeing the rest of the + data initialized. However, this is not possible. But + the new value of '_cffi_call_python' is the function + 'cffi_call_python()' from _cffi_backend. So: */ + cffi_write_barrier(); + /* ^^^ we put a write barrier here, and a corresponding + read barrier at the start of cffi_call_python(). This + ensures that after that read barrier, we see everything + done here before the write barrier. + */ + + assert(_cffi_call_python_org != NULL); + _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; + } + else { + /* initialization failed. Reset this to NULL, even if it was + already set to some other value. Future calls to + _cffi_start_python() are still forced to occur, and will + always return NULL from now on. */ + _cffi_call_python_org = NULL; + } + } + +#ifndef SGX + _cffi_release_reentrant_mutex(); +#endif + + return (_cffi_call_python_fnptr)_cffi_call_python_org; +} + +static +void _cffi_start_and_call_python(struct _cffi_externpy_s *externpy, char *args) +{ + _cffi_call_python_fnptr fnptr; + int current_err = errno; +#ifdef _MSC_VER + int current_lasterr = GetLastError(); +#endif + fnptr = _cffi_start_python(); + if (fnptr == NULL) { + fprintf(stderr, "function %s() called, but initialization code " + "failed. Returning 0.\n", externpy->name); + memset(args, 0, externpy->size_of_result); + } +#ifdef _MSC_VER + SetLastError(current_lasterr); +#endif + errno = current_err; + + if (fnptr != NULL) + fnptr(externpy, args); +} + + +/* The cffi_start_python() function makes sure Python is initialized + and our cffi module is set up. It can be called manually from the + user C code. The same effect is obtained automatically from any + dll-exported ``extern "Python"`` function. This function returns + -1 if initialization failed, 0 if all is OK. */ +_CFFI_UNUSED_FN +static int cffi_start_python(void) +{ + if (_cffi_call_python == &_cffi_start_and_call_python) { + if (_cffi_start_python() == NULL) + return -1; + } + cffi_read_barrier(); + return 0; +} + +#undef cffi_compare_and_swap +#undef cffi_write_barrier +#undef cffi_read_barrier + +#ifdef __cplusplus +} +#endif + +/************************************************************/ + + + +/************************************************************/ + +static void *_cffi_types[] = { +/* 0 */ _CFFI_OP(_CFFI_OP_FUNCTION, 10), // int()(char const *) +/* 1 */ _CFFI_OP(_CFFI_OP_POINTER, 7), // char const * +/* 2 */ _CFFI_OP(_CFFI_OP_FUNCTION_END, 0), +/* 3 */ _CFFI_OP(_CFFI_OP_FUNCTION, 10), // int()(char const *, char const *) +/* 4 */ _CFFI_OP(_CFFI_OP_NOOP, 1), +/* 5 */ _CFFI_OP(_CFFI_OP_NOOP, 1), +/* 6 */ _CFFI_OP(_CFFI_OP_FUNCTION_END, 0), +/* 7 */ _CFFI_OP(_CFFI_OP_PRIMITIVE, 2), // char +/* 8 */ _CFFI_OP(_CFFI_OP_POINTER, 0), // int(*)(char const *) +/* 9 */ _CFFI_OP(_CFFI_OP_POINTER, 3), // int(*)(char const *, char const *) +/* 10 */ _CFFI_OP(_CFFI_OP_PRIMITIVE, 7), // int +}; + +static struct _cffi_externpy_s _cffi_externpy__acs_announce_fact = + { "acs_py_enclave.acs_announce_fact", (int)sizeof(int) }; + +CFFI_DLLEXPORT int acs_announce_fact(char const * a0, char const * a1) +{ + char a[16]; + char *p = a; + *(char const * *)(p + 0) = a0; + *(char const * *)(p + 8) = a1; + _cffi_call_python(&_cffi_externpy__acs_announce_fact, p); + return *(int *)p; +} + +static struct _cffi_externpy_s _cffi_externpy__acs_enforce_request = + { "acs_py_enclave.acs_enforce_request", (int)sizeof(int) }; + +CFFI_DLLEXPORT int acs_enforce_request(char const * a0, char const * a1) +{ + char a[16]; + char *p = a; + *(char const * *)(p + 0) = a0; + *(char const * *)(p + 8) = a1; + _cffi_call_python(&_cffi_externpy__acs_enforce_request, p); + return *(int *)p; +} + +static struct _cffi_externpy_s _cffi_externpy__acs_setup_model = + { "acs_py_enclave.acs_setup_model", (int)sizeof(int) }; + +CFFI_DLLEXPORT int acs_setup_model(char const * a0) +{ + char a[8]; + char *p = a; + *(char const * *)(p + 0) = a0; + _cffi_call_python(&_cffi_externpy__acs_setup_model, p); + return *(int *)p; +} + +static const struct _cffi_global_s _cffi_globals[] = { + { "acs_announce_fact", (void *)&_cffi_externpy__acs_announce_fact, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 9), (void *)acs_announce_fact }, + { "acs_enforce_request", (void *)&_cffi_externpy__acs_enforce_request, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 9), (void *)acs_enforce_request }, + { "acs_setup_model", (void *)&_cffi_externpy__acs_setup_model, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 8), (void *)acs_setup_model }, +}; + +static const struct _cffi_type_context_s _cffi_type_context = { + _cffi_types, + _cffi_globals, + NULL, /* no fields */ + NULL, /* no struct_unions */ + NULL, /* no enums */ + NULL, /* no typenames */ + 3, /* num_globals */ + 0, /* num_struct_unions */ + 0, /* num_enums */ + 0, /* num_typenames */ + NULL, /* no includes */ + 11, /* num_types */ + 1, /* flags */ +}; + +#ifdef __GNUC__ +# pragma GCC visibility push(default) /* for -fvisibility= */ +#endif + +#ifdef PYPY_VERSION +PyMODINIT_FUNC +_cffi_pypyinit_acs_py_enclave(const void *p[]) +{ + if (((intptr_t)p[0]) >= 0x0A03) { + _cffi_call_python_org = (void(*)(struct _cffi_externpy_s *, char *))p[1]; + } + p[0] = (const void *)0x2701; + p[1] = &_cffi_type_context; +#if PY_MAJOR_VERSION >= 3 + return NULL; +#endif +} +# ifdef _MSC_VER + PyMODINIT_FUNC +# if PY_MAJOR_VERSION >= 3 + PyInit_acs_py_enclave(void) { return NULL; } +# else + initacs_py_enclave(void) { } +# endif +# endif +#elif PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC +PyInit_acs_py_enclave(void) +{ + return _cffi_init("acs_py_enclave", 0x2701, &_cffi_type_context); +} +#else +PyMODINIT_FUNC +initacs_py_enclave(void) +{ + _cffi_init("acs_py_enclave", 0x2701, &_cffi_type_context); +} +#endif + +#ifdef __GNUC__ +# pragma GCC visibility pop +#endif diff --git a/third_party/mesapy b/third_party/mesapy deleted file mode 160000 index 947fb3f5..00000000 --- a/third_party/mesapy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 947fb3f598eede83ba0e33b5b5655b9a9597c2d8 --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
