├── .clang-format ├── .clang-tidy ├── .github └── workflows │ ├── pyjs_builder.yml │ ├── pyjs_matrix_os.yml │ ├── pyjs_matrix_variants.yml │ └── python_builder.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CMakeLists.txt ├── Doxyfile ├── FAQ.md ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── docs ├── mpyx.maxref.xml ├── py.maxref.xml ├── pyjs.maxref.xml └── pymx.maxref.xml ├── examples ├── README.md ├── demos │ └── hello.py ├── servers │ ├── README.md │ └── pyserver.py └── tests │ ├── test_api.py │ ├── test_api_array.py │ ├── test_api_atom.py │ ├── test_api_atomarray.py │ ├── test_api_atombuf.py │ ├── test_api_binbuf.py │ ├── test_api_box.py │ ├── test_api_buffer.py │ ├── test_api_buffer_array.py │ ├── test_api_buffer_np.py │ ├── test_api_buffer_scipy.py │ ├── test_api_coll.py │ ├── test_api_database.py │ ├── test_api_dictionary.py │ ├── test_api_functions.py │ ├── test_api_hashtab.py │ ├── test_api_linklist.py │ ├── test_api_matrix.py │ ├── test_api_matrix_np.py │ ├── test_api_max.py │ ├── test_api_maxobject.py │ ├── test_api_patcher.py │ ├── test_api_path.py │ ├── test_api_perf.py │ ├── test_api_pyexternal.py │ ├── test_api_table.py │ └── test_functional.py ├── help ├── cobra.maxhelp ├── demo.maxhelp ├── jit.fill2.maxhelp ├── jit.foo.maxhelp ├── jmx.maxhelp ├── krait.maxhelp ├── mamba.maxhelp ├── mpy.maxhelp ├── mpyx.maxhelp ├── mx.maxhelp ├── mxpy.maxhelp ├── pktpy.maxhelp ├── pktpy2.maxhelp ├── py.maxhelp ├── pyjs.maxhelp ├── pymx.maxhelp ├── pyx.maxhelp ├── shell.maxhelp ├── xpyc.maxhelp ├── zedit.maxhelp ├── zpy.maxhelp └── ztp.maxhelp ├── init └── py-fileformats.txt ├── javascript ├── package-lock.json ├── package.json ├── pynode.js ├── test_pyjs.js └── test_pynode.py ├── jsextensions └── maxclasswrap.js ├── media ├── .keep ├── py-maxhelp.png └── xkcd-python-environment.png ├── patchers ├── README.md ├── abstractions │ └── py_external_editor.maxpat ├── bpatchers_py │ ├── coll_linebuffer5.7.maxpat │ ├── py_coll_repl.maxpat │ └── py_repl_plus.maxpat ├── bpatchers_ui │ ├── py_extedit.maxpat │ ├── py_multiedit.maxpat │ ├── py_repl.maxpat │ ├── py_textedit.maxpat │ └── pyjs_repl.maxpat └── tests │ ├── _breaking │ └── zlib-not-available │ │ ├── README.md │ │ ├── performance_single.maxpat │ │ ├── performance_single_send.maxpat │ │ ├── py_crash.maxpat │ │ ├── py_fix_rm_v8.maxpat │ │ └── py_fix_rm_v8_js.maxpat │ ├── scratch │ ├── matrix1.maxpat │ └── matrix2.maxpat │ ├── test_api │ ├── test_api_array.maxpat │ ├── test_api_atom.maxpat │ ├── test_api_atombuf.maxpat │ ├── test_api_binbuf.maxpat │ ├── test_api_box.maxpat │ ├── test_api_buffer.maxpat │ ├── test_api_buffer_array.maxpat │ ├── test_api_buffer_np.maxpat │ ├── test_api_coll.maxpat │ ├── test_api_database.maxpat │ ├── test_api_dictionary.maxpat │ ├── test_api_functions.maxpat │ ├── test_api_hashtab.maxpat │ ├── test_api_matrix.maxpat │ ├── test_api_matrix_np.maxpat │ ├── test_api_max.maxpat │ ├── test_api_maxobject.maxpat │ ├── test_api_memory.maxpat │ ├── test_api_patcher.maxpat │ ├── test_api_path.maxpat │ ├── test_api_pyexternal.maxpat │ └── test_api_table.maxpat │ ├── test_matrix │ ├── test_convert_2d_3d.maxpat │ ├── test_fill2_setdata.maxpat │ ├── test_jit_fill.maxpat │ └── test_jit_pack_offset.maxpat │ ├── test_maxtests │ ├── _template-maxtest.maxpat │ ├── test_call.maxtest.maxpat │ ├── test_dual_api.maxtext.maxpat │ ├── test_eval_list.maxtest.maxpat │ ├── test_execfile.maxtest.maxpat │ ├── test_instances.maxpat │ ├── test_load.maxtest.maxpat │ ├── test_math.maxtest.maxpat │ ├── test_pipe_exec.maxtest.maxpat │ ├── test_pipe_import.maxtest.maxpat │ ├── test_pipe_list.maxtest.maxpat │ ├── test_pipe_scalar.maxtest.maxpat │ ├── test_pipe_string.maxtest.maxpat │ └── test_send.maxtest.maxpat │ ├── test_py_attributes │ ├── test_autoload.maxpat │ ├── test_autoload_notext.maxpat │ └── test_pythonpath.maxpat │ ├── test_py_editing │ ├── test_blocking_repl.maxpat │ ├── test_editor_save.maxpat │ ├── test_py_coll.maxpat │ ├── test_py_env_editor.maxpat │ ├── test_py_extedit.maxpat │ ├── test_py_external_editor.maxpat │ ├── test_py_gl_repl.maxpat │ ├── test_py_textedit.maxpat │ └── test_udp.maxpat │ ├── test_py_methods │ ├── test_blocking.maxpat │ ├── test_dict.maxpat │ ├── test_external_lib.maxpat │ ├── test_func_signature.maxpat │ ├── test_isolation.maxpat │ ├── test_numpy.maxpat │ ├── test_py_shell.maxpat │ ├── test_quoting.maxpat │ ├── test_run.maxpat │ └── test_sched.maxpat │ ├── test_py_web │ ├── test_jweb │ │ ├── demo.html │ │ ├── demo.js │ │ └── test_jweb.maxpat │ ├── test_pynode │ │ ├── test_pynode.maxpat │ │ └── test_pynode_shell.maxpat │ ├── test_pyodide │ │ └── test_pyodide.maxpat │ └── test_pyscript │ │ ├── antigravity.py │ │ ├── antigravity.svg │ │ ├── code.html │ │ ├── complex.html │ │ ├── hello.html │ │ ├── repl.html │ │ ├── run_server.sh │ │ ├── test_pyscript.maxpat │ │ └── utils.py │ ├── test_pyjs │ └── test_pyjs_v8.maxpat │ ├── test_scripting │ └── test_scripting_buffer.maxpat │ ├── test_standalone │ ├── test_standalone_dual.maxpat │ ├── test_standalone_py.maxpat │ └── test_standalone_pyjs.maxpat │ ├── test_v8 │ └── test_v8_setgetvalueof.maxpat │ └── test_ztp │ └── test_ztp_shell.maxpat ├── requirements.txt ├── source ├── demos │ ├── README.md │ ├── cmx │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── cmx.c │ │ ├── cmx.cpp │ │ └── cmx.h │ ├── demo │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── demo.c │ └── mx │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── mx.c ├── docs │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── _archive │ │ └── intro.qmd │ ├── _book │ │ └── Python3-Externals-for-Max-MSP.pdf │ ├── _quarto.yml │ ├── index.qmd │ ├── scripts │ │ └── update.py │ ├── src │ │ ├── building │ │ │ ├── overview.qmd │ │ │ └── packaging.qmd │ │ ├── dev │ │ │ ├── build-times.txt │ │ │ ├── builder │ │ │ │ ├── build-graph.d2 │ │ │ │ ├── build-graph.png │ │ │ │ ├── build-graph.svg │ │ │ │ ├── building-on-apple-silicon.qmd │ │ │ │ ├── building-pyext-flext.qmd │ │ │ │ ├── cmake.qmd │ │ │ │ ├── codesign-notarize.qmd │ │ │ │ ├── fix_arm64_bug.qmd │ │ │ │ ├── github-actions.qmd │ │ │ │ ├── make-dmg.qmd │ │ │ │ ├── mappings.qmd │ │ │ │ ├── matrix.xlsx │ │ │ │ ├── relocatable-python.qmd │ │ │ │ ├── remove-detritus.qmd │ │ │ │ ├── switching-between-modes.qmd │ │ │ │ ├── xcconfig.qmd │ │ │ │ └── xcode-concepts.qmd │ │ │ ├── devguide.qmd │ │ │ ├── general │ │ │ │ └── xcodebuild.md │ │ │ ├── py │ │ │ │ ├── buffer-protocol.qmd │ │ │ │ ├── buffer.qmd │ │ │ │ ├── bugs.qmd │ │ │ │ ├── build-options.qmd │ │ │ │ ├── cython.qmd │ │ │ │ ├── design.qmd │ │ │ │ ├── dont.qmd │ │ │ │ ├── editor.qmd │ │ │ │ ├── escape_text.qmd │ │ │ │ ├── experiments.qmd │ │ │ │ ├── max-c-api.qmd │ │ │ │ ├── max-fileformats.qmd │ │ │ │ ├── numpy-error.qmd │ │ │ │ ├── python-c-api.qmd │ │ │ │ ├── python-shell-via-nodejs.qmd │ │ │ │ ├── repl.qmd │ │ │ │ ├── scripting-tips.qmd │ │ │ │ ├── shared-python-problem.qmd │ │ │ │ ├── snippets.qmd │ │ │ │ ├── threading.qmd │ │ │ │ ├── type-translation.qmd │ │ │ │ └── types.qmd │ │ │ └── pyjs │ │ │ │ ├── javascript.qmd │ │ │ │ └── pyjs-nodejs │ │ │ │ ├── @fridgerator-pynode - npm.webloc │ │ │ │ ├── @savearray2-py.js - npm.webloc │ │ │ │ ├── Almenon-AREPL-vscode- program python in real-time.webloc │ │ │ │ ├── Brython.webloc │ │ │ │ ├── CodeMirror.webloc │ │ │ │ ├── Gottox-node-webterm- simple demo application for child_pty and terminal.js..webloc │ │ │ │ ├── arepl-backend - npm.webloc │ │ │ │ ├── awesome-react-repl - npm.webloc │ │ │ │ ├── brython - npm.webloc │ │ │ │ ├── eclipse-theia-theia- Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript..webloc │ │ │ │ ├── jupyter │ │ │ │ ├── @aminya-jmp - npm.webloc │ │ │ │ ├── @jupyterlab-services - npm.webloc │ │ │ │ ├── @nteract-kernel-relay - npm.webloc │ │ │ │ ├── @nteract-messaging - npm.webloc │ │ │ │ ├── enchannel-zmq-backend - npm.webloc │ │ │ │ ├── ipycallback - npm.webloc │ │ │ │ ├── jmp-zeromq6 - npm.webloc │ │ │ │ └── n-riesco-jmp- Node.js module for creating, parsing and replying to messages of the Jupyter Messaging….webloc │ │ │ │ ├── pyconnector - npm.webloc │ │ │ │ ├── python-bridge - npm.webloc │ │ │ │ ├── python-shell - npm.webloc │ │ │ │ ├── python-shell.js │ │ │ │ ├── terminal.js - npm.webloc │ │ │ │ └── zeromq - npm.webloc │ │ ├── externals │ │ │ ├── cmx.qmd │ │ │ ├── cobra.qmd │ │ │ ├── demo.qmd │ │ │ ├── jmx.qmd │ │ │ ├── krait.qmd │ │ │ ├── mamba.qmd │ │ │ ├── mpy.qmd │ │ │ ├── mpyx.qmd │ │ │ ├── mxpy.qmd │ │ │ ├── pktpy.qmd │ │ │ ├── pktpy2.qmd │ │ │ ├── py.qmd │ │ │ ├── pyjs.qmd │ │ │ ├── pyx.qmd │ │ │ ├── shell.qmd │ │ │ ├── xpyc.qmd │ │ │ ├── zedit.qmd │ │ │ ├── zpy.qmd │ │ │ └── ztp.qmd │ │ ├── faq.qmd │ │ ├── media │ │ │ ├── .keep │ │ │ ├── py-maxhelp.png │ │ │ └── xkcd-python-environment.png │ │ ├── overview.qmd │ │ ├── references.bib │ │ └── references.qmd │ └── workbook.leo ├── maxmspsdk.xcconfig ├── min-api │ ├── .gitignore │ ├── Authors.md │ ├── CMakeLists.txt │ ├── License.md │ ├── ReadMe.md │ ├── doc │ │ ├── API-Attribute.md │ │ ├── API-Buffer.md │ │ ├── GuideToAudio.md │ │ ├── GuideToDataspaces.md │ │ ├── GuideToInitialization.md │ │ ├── GuideToSpecialMethods.md │ │ ├── GuideToThreading.md │ │ ├── GuideToUserInterfaceObjects.md │ │ ├── GuideToWhereToLook.md │ │ ├── GuideToWritingObjects.md │ │ └── doxyfile.in │ ├── include │ │ ├── c74_min.h │ │ ├── c74_min_api.h │ │ ├── c74_min_argument.h │ │ ├── c74_min_atom.h │ │ ├── c74_min_attribute.h │ │ ├── c74_min_attribute_impl.h │ │ ├── c74_min_buffer.h │ │ ├── c74_min_buffer_impl.h │ │ ├── c74_min_catch.h │ │ ├── c74_min_dataspace.h │ │ ├── c74_min_dataspace_gain.h │ │ ├── c74_min_dataspace_none.h │ │ ├── c74_min_dataspace_time.h │ │ ├── c74_min_dictionary.h │ │ ├── c74_min_doc.h │ │ ├── c74_min_event.h │ │ ├── c74_min_flags.h │ │ ├── c74_min_graphics.h │ │ ├── c74_min_impl.h │ │ ├── c74_min_inlet.h │ │ ├── c74_min_limit.h │ │ ├── c74_min_logger.h │ │ ├── c74_min_message.h │ │ ├── c74_min_notification.h │ │ ├── c74_min_object.h │ │ ├── c74_min_object_components.h │ │ ├── c74_min_object_wrapper.h │ │ ├── c74_min_operator_matrix.h │ │ ├── c74_min_operator_mc.h │ │ ├── c74_min_operator_sample.h │ │ ├── c74_min_operator_ui.h │ │ ├── c74_min_operator_vector.h │ │ ├── c74_min_outlet.h │ │ ├── c74_min_patcher.h │ │ ├── c74_min_path.h │ │ ├── c74_min_port.h │ │ ├── c74_min_queue.h │ │ ├── c74_min_string.h │ │ ├── c74_min_symbol.h │ │ ├── c74_min_texteditor.h │ │ ├── c74_min_threadsafety.h │ │ ├── c74_min_time.h │ │ ├── c74_min_timer.h │ │ ├── c74_min_unittest.h │ │ ├── murmur │ │ │ ├── Murmur3.h │ │ │ └── main.cpp │ │ └── readerwriterqueue │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ ├── LICENSE.md │ │ │ ├── README.md │ │ │ ├── atomicops.h │ │ │ ├── benchmarks │ │ │ ├── bench.cpp │ │ │ ├── ext │ │ │ │ ├── 1024cores │ │ │ │ │ └── spscqueue.h │ │ │ │ └── folly │ │ │ │ │ └── ProducerConsumerQueue.h │ │ │ ├── makefile │ │ │ ├── msvc10 │ │ │ │ ├── winbench-intel.vcxproj │ │ │ │ ├── winbench-intel.vcxproj.filters │ │ │ │ ├── winbench.vcxproj │ │ │ │ └── winbench.vcxproj.filters │ │ │ ├── msvc12 │ │ │ │ ├── winbench-intel.vcxproj │ │ │ │ ├── winbench-intel.vcxproj.filters │ │ │ │ ├── winbench.vcxproj │ │ │ │ └── winbench.vcxproj.filters │ │ │ ├── msvc14 │ │ │ │ ├── winbench-intel.vcxproj │ │ │ │ ├── winbench-intel.vcxproj.filters │ │ │ │ ├── winbench.vcxproj │ │ │ │ └── winbench.vcxproj.filters │ │ │ ├── systemtime.cpp │ │ │ └── systemtime.h │ │ │ ├── readerwriterqueue.h │ │ │ └── tests │ │ │ ├── common │ │ │ ├── simplethread.cpp │ │ │ └── simplethread.h │ │ │ ├── stabtest │ │ │ ├── makefile │ │ │ ├── msvc10 │ │ │ │ ├── stabtest.vcxproj │ │ │ │ └── stabtest.vcxproj.filters │ │ │ ├── msvc12 │ │ │ │ ├── stabtest.vcxproj │ │ │ │ └── stabtest.vcxproj.filters │ │ │ └── stabtest.cpp │ │ │ └── unittests │ │ │ ├── makefile │ │ │ ├── minitest.h │ │ │ ├── msvc10 │ │ │ ├── unittests.vcxproj │ │ │ └── unittests.vcxproj.filters │ │ │ ├── msvc12 │ │ │ ├── unittests.vcxproj │ │ │ └── unittests.vcxproj.filters │ │ │ └── unittests.cpp │ └── script │ │ ├── min-package.cmake │ │ ├── min-posttarget.cmake │ │ ├── min-pretarget.cmake │ │ └── pre-commit ├── min-lib │ ├── .gitignore │ ├── Authors.md │ ├── CMakeLists.txt │ ├── License.md │ ├── ReadMe.md │ └── include │ │ ├── c74_lib.h │ │ ├── c74_lib_adsr.h │ │ ├── c74_lib_allpass.h │ │ ├── c74_lib_circular_storage.h │ │ ├── c74_lib_dcblocker.h │ │ ├── c74_lib_delay.h │ │ ├── c74_lib_easing.h │ │ ├── c74_lib_filters.h │ │ ├── c74_lib_generator.h │ │ ├── c74_lib_interpolator.h │ │ ├── c74_lib_limiter.h │ │ ├── c74_lib_math.h │ │ ├── c74_lib_onepole.h │ │ ├── c74_lib_oscillator.h │ │ ├── c74_lib_saturation.h │ │ └── c74_lib_sync.h ├── projects │ ├── Info.plist │ ├── README.md │ ├── cobra │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── cobra.cpp │ │ └── py_interpreter.h │ ├── jmx │ │ ├── CMakeLists.txt │ │ ├── NOTES.md │ │ ├── README.md │ │ ├── jmx.c │ │ ├── server.py │ │ └── tests │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── client.py │ │ │ ├── jupyter_client │ │ │ ├── test_kernelclient.py │ │ │ └── test_kernelclient2.py │ │ │ ├── pseudoterminal.py │ │ │ ├── ptycat.c │ │ │ ├── pyclient.c │ │ │ ├── test_czmq_client.c │ │ │ ├── test_czmq_server.c │ │ │ ├── test_pczmq_client.c │ │ │ ├── test_pczmq_server.c │ │ │ ├── test_pzmq_client.c │ │ │ ├── test_pzmq_server.c │ │ │ ├── test_spawn.c │ │ │ ├── test_zmq_client.c │ │ │ └── test_zmq_server.c │ ├── krait │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── krait.c │ ├── mamba │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── mamba.c │ │ └── py.h │ ├── mpy │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── micropython.cmake │ │ ├── micropython_embed │ │ │ ├── extmod │ │ │ │ └── modplatform.h │ │ │ ├── genhdr │ │ │ │ ├── moduledefs.h │ │ │ │ ├── mpversion.h │ │ │ │ ├── qstrdefs.generated.h │ │ │ │ └── root_pointers.h │ │ │ ├── port │ │ │ │ ├── embed_util.c │ │ │ │ ├── micropython_embed.h │ │ │ │ ├── mpconfigport_common.h │ │ │ │ ├── mphalport.c │ │ │ │ └── mphalport.h │ │ │ ├── py │ │ │ │ ├── argcheck.c │ │ │ │ ├── asmarm.c │ │ │ │ ├── asmarm.h │ │ │ │ ├── asmbase.c │ │ │ │ ├── asmbase.h │ │ │ │ ├── asmthumb.c │ │ │ │ ├── asmthumb.h │ │ │ │ ├── asmx64.c │ │ │ │ ├── asmx64.h │ │ │ │ ├── asmx86.c │ │ │ │ ├── asmx86.h │ │ │ │ ├── asmxtensa.c │ │ │ │ ├── asmxtensa.h │ │ │ │ ├── bc.c │ │ │ │ ├── bc.h │ │ │ │ ├── bc0.h │ │ │ │ ├── binary.c │ │ │ │ ├── binary.h │ │ │ │ ├── builtin.h │ │ │ │ ├── builtinevex.c │ │ │ │ ├── builtinhelp.c │ │ │ │ ├── builtinimport.c │ │ │ │ ├── compile.c │ │ │ │ ├── compile.h │ │ │ │ ├── dynruntime.h │ │ │ │ ├── emit.h │ │ │ │ ├── emitbc.c │ │ │ │ ├── emitcommon.c │ │ │ │ ├── emitglue.c │ │ │ │ ├── emitglue.h │ │ │ │ ├── emitinlinethumb.c │ │ │ │ ├── emitinlinextensa.c │ │ │ │ ├── emitnarm.c │ │ │ │ ├── emitnative.c │ │ │ │ ├── emitnthumb.c │ │ │ │ ├── emitnx64.c │ │ │ │ ├── emitnx86.c │ │ │ │ ├── emitnxtensa.c │ │ │ │ ├── emitnxtensawin.c │ │ │ │ ├── formatfloat.c │ │ │ │ ├── formatfloat.h │ │ │ │ ├── frozenmod.c │ │ │ │ ├── frozenmod.h │ │ │ │ ├── gc.c │ │ │ │ ├── gc.h │ │ │ │ ├── grammar.h │ │ │ │ ├── lexer.c │ │ │ │ ├── lexer.h │ │ │ │ ├── malloc.c │ │ │ │ ├── map.c │ │ │ │ ├── misc.h │ │ │ │ ├── modarray.c │ │ │ │ ├── modbuiltins.c │ │ │ │ ├── modcmath.c │ │ │ │ ├── modcollections.c │ │ │ │ ├── moderrno.c │ │ │ │ ├── modgc.c │ │ │ │ ├── modio.c │ │ │ │ ├── modmath.c │ │ │ │ ├── modmicropython.c │ │ │ │ ├── modstruct.c │ │ │ │ ├── modsys.c │ │ │ │ ├── modthread.c │ │ │ │ ├── mpconfig.h │ │ │ │ ├── mperrno.h │ │ │ │ ├── mphal.h │ │ │ │ ├── mpprint.c │ │ │ │ ├── mpprint.h │ │ │ │ ├── mpstate.c │ │ │ │ ├── mpstate.h │ │ │ │ ├── mpthread.h │ │ │ │ ├── mpz.c │ │ │ │ ├── mpz.h │ │ │ │ ├── nativeglue.c │ │ │ │ ├── nativeglue.h │ │ │ │ ├── nlr.c │ │ │ │ ├── nlr.h │ │ │ │ ├── nlraarch64.c │ │ │ │ ├── nlrmips.c │ │ │ │ ├── nlrpowerpc.c │ │ │ │ ├── nlrsetjmp.c │ │ │ │ ├── nlrthumb.c │ │ │ │ ├── nlrx64.c │ │ │ │ ├── nlrx86.c │ │ │ │ ├── nlrxtensa.c │ │ │ │ ├── obj.c │ │ │ │ ├── obj.h │ │ │ │ ├── objarray.c │ │ │ │ ├── objarray.h │ │ │ │ ├── objattrtuple.c │ │ │ │ ├── objbool.c │ │ │ │ ├── objboundmeth.c │ │ │ │ ├── objcell.c │ │ │ │ ├── objclosure.c │ │ │ │ ├── objcomplex.c │ │ │ │ ├── objdeque.c │ │ │ │ ├── objdict.c │ │ │ │ ├── objenumerate.c │ │ │ │ ├── objexcept.c │ │ │ │ ├── objexcept.h │ │ │ │ ├── objfilter.c │ │ │ │ ├── objfloat.c │ │ │ │ ├── objfun.c │ │ │ │ ├── objfun.h │ │ │ │ ├── objgenerator.c │ │ │ │ ├── objgenerator.h │ │ │ │ ├── objgetitemiter.c │ │ │ │ ├── objint.c │ │ │ │ ├── objint.h │ │ │ │ ├── objint_longlong.c │ │ │ │ ├── objint_mpz.c │ │ │ │ ├── objlist.c │ │ │ │ ├── objlist.h │ │ │ │ ├── objmap.c │ │ │ │ ├── objmodule.c │ │ │ │ ├── objmodule.h │ │ │ │ ├── objnamedtuple.c │ │ │ │ ├── objnamedtuple.h │ │ │ │ ├── objnone.c │ │ │ │ ├── objobject.c │ │ │ │ ├── objpolyiter.c │ │ │ │ ├── objproperty.c │ │ │ │ ├── objrange.c │ │ │ │ ├── objreversed.c │ │ │ │ ├── objset.c │ │ │ │ ├── objsingleton.c │ │ │ │ ├── objslice.c │ │ │ │ ├── objstr.c │ │ │ │ ├── objstr.h │ │ │ │ ├── objstringio.c │ │ │ │ ├── objstringio.h │ │ │ │ ├── objstrunicode.c │ │ │ │ ├── objtuple.c │ │ │ │ ├── objtuple.h │ │ │ │ ├── objtype.c │ │ │ │ ├── objtype.h │ │ │ │ ├── objzip.c │ │ │ │ ├── opmethods.c │ │ │ │ ├── pairheap.c │ │ │ │ ├── pairheap.h │ │ │ │ ├── parse.c │ │ │ │ ├── parse.h │ │ │ │ ├── parsenum.c │ │ │ │ ├── parsenum.h │ │ │ │ ├── parsenumbase.c │ │ │ │ ├── parsenumbase.h │ │ │ │ ├── persistentcode.c │ │ │ │ ├── persistentcode.h │ │ │ │ ├── profile.c │ │ │ │ ├── profile.h │ │ │ │ ├── pystack.c │ │ │ │ ├── pystack.h │ │ │ │ ├── qstr.c │ │ │ │ ├── qstr.h │ │ │ │ ├── qstrdefs.h │ │ │ │ ├── reader.c │ │ │ │ ├── reader.h │ │ │ │ ├── repl.c │ │ │ │ ├── repl.h │ │ │ │ ├── ringbuf.c │ │ │ │ ├── ringbuf.h │ │ │ │ ├── runtime.c │ │ │ │ ├── runtime.h │ │ │ │ ├── runtime0.h │ │ │ │ ├── runtime_utils.c │ │ │ │ ├── scheduler.c │ │ │ │ ├── scope.c │ │ │ │ ├── scope.h │ │ │ │ ├── sequence.c │ │ │ │ ├── showbc.c │ │ │ │ ├── smallint.c │ │ │ │ ├── smallint.h │ │ │ │ ├── stackctrl.c │ │ │ │ ├── stackctrl.h │ │ │ │ ├── stream.c │ │ │ │ ├── stream.h │ │ │ │ ├── unicode.c │ │ │ │ ├── unicode.h │ │ │ │ ├── vm.c │ │ │ │ ├── vmentrytable.h │ │ │ │ ├── vstr.c │ │ │ │ └── warning.c │ │ │ └── shared │ │ │ │ └── runtime │ │ │ │ ├── gchelper.h │ │ │ │ └── gchelper_generic.c │ │ ├── mpconfigport.h │ │ └── mpy.c │ ├── mpyx │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── DEVNOTES.md │ │ ├── README.md │ │ ├── mpy_interpreter.h │ │ ├── mpyx.cpp │ │ └── tests │ │ │ └── test_span_vec.cpp │ ├── mxpy │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── mxpy.c │ │ └── python_help.py │ ├── pktpy │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── TODO.md │ │ ├── pktpy.cpp │ │ ├── pktpy.h │ │ ├── pocketpy.h │ │ ├── scripts │ │ │ └── demo.py │ │ └── tests │ │ │ ├── inherit │ │ │ ├── build.sh │ │ │ └── main.cpp │ │ │ ├── pocketpy_dylib │ │ │ ├── CMakeLists.txt │ │ │ ├── README.md │ │ │ ├── dsp.c │ │ │ ├── export.h │ │ │ ├── pocketpy_c.c │ │ │ └── pocketpy_c.h │ │ │ ├── repl │ │ │ └── main.cpp │ │ │ ├── test_c │ │ │ ├── build.sh │ │ │ └── demo.cpp │ │ │ ├── test_cpp │ │ │ ├── build.sh │ │ │ ├── demo.cpp │ │ │ └── test.py │ │ │ ├── test_cpp2 │ │ │ ├── build.sh │ │ │ └── demo.cpp │ │ │ └── test_str_replace │ │ │ ├── main │ │ │ └── main.cpp │ ├── pktpy2 │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── TODO.md │ │ ├── pktpy2.c │ │ ├── pktpy2.h │ │ ├── pktpy2_api.h │ │ └── tests │ │ │ ├── call │ │ │ ├── f_args.c │ │ │ └── f_kwds.c │ │ │ ├── call_py_func │ │ │ └── call_py_func.c │ │ │ ├── casting │ │ │ └── casting.c │ │ │ ├── person │ │ │ └── person.c │ │ │ ├── print_args │ │ │ └── print_args.c │ │ │ ├── simple_struct │ │ │ └── simple_struct.c │ │ │ ├── test_iter │ │ │ ├── Makefile │ │ │ └── test_iter.c │ │ │ └── variadic │ │ │ └── test_variadic.c │ ├── py │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── TODO.md │ │ ├── api.c │ │ ├── api.h │ │ ├── api.md │ │ ├── api.pyx │ │ ├── api_jit.pxd │ │ ├── api_max.pxd │ │ ├── api_msp.pxd │ │ ├── api_py.pxd │ │ ├── builder │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── __main__.py │ │ │ ├── cli.py │ │ │ ├── config.py │ │ │ ├── core.py │ │ │ ├── depend.py │ │ │ ├── ext │ │ │ │ ├── __init__.py │ │ │ │ ├── pbar.py │ │ │ │ └── relocatable_python │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── __main__.py │ │ │ │ │ ├── fix.py │ │ │ │ │ ├── get.py │ │ │ │ │ ├── install.py │ │ │ │ │ ├── relocatablizer.py │ │ │ │ │ ├── requirements_python2_recommended.txt │ │ │ │ │ ├── requirements_python3_recommended.txt │ │ │ │ │ └── research_notes.txt │ │ │ ├── factory.py │ │ │ ├── install.py │ │ │ ├── package.py │ │ │ ├── patch.py │ │ │ ├── setup-map.txt │ │ │ ├── shell.py │ │ │ └── utils.py │ │ ├── notes │ │ │ ├── build-times.md │ │ │ ├── build-variants.md │ │ │ ├── limitedapi-py.md │ │ │ ├── optimization.md │ │ │ ├── ref-analysis.txt │ │ │ ├── refcounting.md │ │ │ └── unused │ │ │ │ ├── api_unused.pyx │ │ │ │ ├── not_available.pyx │ │ │ │ ├── py_unused.c │ │ │ │ └── scratch.pyx │ │ ├── py.c │ │ ├── py.h │ │ ├── py_prelude.h │ │ ├── py_prelude.py │ │ ├── pyjs.c │ │ ├── pyjs.h │ │ ├── resources │ │ │ ├── cflow │ │ │ │ ├── ignore.txt │ │ │ │ ├── mamba_cflow0.pdf │ │ │ │ └── py_cflow0.pdf │ │ │ ├── entitlements │ │ │ │ └── entitlements.plist │ │ │ ├── patch │ │ │ │ ├── 3.10 │ │ │ │ │ ├── Setup.orig │ │ │ │ │ ├── Setup.orig-diff-from-3.9.diff │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── makesetup.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-api.local │ │ │ │ │ ├── setup-static-min.local │ │ │ │ │ ├── setup-static-min2.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min4.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ ├── setup-static-min6.local │ │ │ │ │ └── setup.beeware │ │ │ │ ├── 3.11 │ │ │ │ │ ├── Setup │ │ │ │ │ ├── Setup.stdlib │ │ │ │ │ ├── analyze.py │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── configure.txt │ │ │ │ │ ├── configure_11_4to5.patch │ │ │ │ │ ├── configure_pre_11_4.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-min2.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ ├── setup-static-min6.local │ │ │ │ │ ├── setup-static.bootstrap │ │ │ │ │ └── setup.beeware │ │ │ │ ├── 3.12 │ │ │ │ │ ├── Setup │ │ │ │ │ ├── Setup.diff │ │ │ │ │ ├── Setup.stdlib │ │ │ │ │ ├── configure.old.patch │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── configure.txt │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min3.old.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ ├── setup-static-min6.local │ │ │ │ │ ├── setup-static.bootstrap │ │ │ │ │ └── setup.beeware │ │ │ │ ├── 3.13 │ │ │ │ │ ├── Setup │ │ │ │ │ ├── Setup.diff │ │ │ │ │ ├── Setup.stdlib │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── configure.txt │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ ├── setup-static-min6.local │ │ │ │ │ └── setup-static.bootstrap │ │ │ │ ├── 3.6 │ │ │ │ │ ├── makesetup.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ └── setup-static-min.local │ │ │ │ ├── 3.7 │ │ │ │ │ ├── Setup.orig │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── makesetup.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-min.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ └── setup-static-min6.local │ │ │ │ ├── 3.8 │ │ │ │ │ ├── Setup.orig │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── makesetup.orig │ │ │ │ │ ├── makesetup.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-min.local │ │ │ │ │ ├── setup-static-min2.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min4.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ └── setup-static-min6.local │ │ │ │ ├── 3.9 │ │ │ │ │ ├── Setup.orig │ │ │ │ │ ├── Setup.orig-diff-from-3.8.diff │ │ │ │ │ ├── configure.patch │ │ │ │ │ ├── makesetup.orig │ │ │ │ │ ├── makesetup.patch │ │ │ │ │ ├── makesetup2.patch │ │ │ │ │ ├── setup-shared.local │ │ │ │ │ ├── setup-static-api.local │ │ │ │ │ ├── setup-static-min.local │ │ │ │ │ ├── setup-static-min2.local │ │ │ │ │ ├── setup-static-min3.local │ │ │ │ │ ├── setup-static-min4.local │ │ │ │ │ ├── setup-static-min5.local │ │ │ │ │ ├── setup-static-min6.0.local │ │ │ │ │ └── setup-static-min6.local │ │ │ │ ├── README.md │ │ │ │ └── python-cmake-buildsystem │ │ │ │ │ └── scproxy.patch │ │ │ ├── pyjs-dependencies.txt │ │ │ ├── specs │ │ │ │ └── python-shared.yml │ │ │ └── workflows │ │ │ │ ├── build_matrix.yml │ │ │ │ ├── pyjs_homebrew.yml │ │ │ │ ├── pyjs_relocatable.yml │ │ │ │ ├── release.yml │ │ │ │ └── workflows.zip │ │ ├── scripts │ │ │ ├── CMakeLists.txt │ │ │ ├── analyze.py │ │ │ ├── b64.py │ │ │ ├── base.sh │ │ │ ├── bash_complete.sh │ │ │ ├── build_dev.sh │ │ │ ├── build_projects.sh │ │ │ ├── build_universal.sh │ │ │ ├── check-big-git-files.sh │ │ │ ├── check_numpy.py │ │ │ ├── cmake-py │ │ │ │ └── CMakeLists.txt │ │ │ ├── cmake-pyjs │ │ │ │ └── CMakeLists.txt │ │ │ ├── entitlements.plist │ │ │ ├── fix-pyjs-standalone.sh │ │ │ ├── get_beeware.py │ │ │ ├── notarize.sh │ │ │ ├── parsegen.py │ │ │ ├── py2c.py │ │ │ ├── rm_disabled_workflow_runs.sh │ │ │ ├── set_py_ver.py │ │ │ ├── shrink-standalone.sh │ │ │ ├── standalone │ │ │ │ ├── build-standalone.txt │ │ │ │ └── custom │ │ │ │ │ ├── javascript │ │ │ │ │ └── test_pyjs.js │ │ │ │ │ └── jsextensions │ │ │ │ │ └── maxclasswrap.js │ │ │ └── stripw.py │ │ ├── targets │ │ │ ├── beeware-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── beeware-pkg │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── common.xcconfig │ │ │ ├── framework-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── framework-pkg │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── homebrew-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── homebrew-pkg │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── local-sys │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── optimize.xcconfig │ │ │ ├── relocatable-pkg │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── shared-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── shared-pkg │ │ │ │ ├── build.py │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── static-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── static-pkg │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── vanilla-ext │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── vanilla-pkg │ │ │ │ ├── py-js.xcconfig │ │ │ │ └── py-js.xcodeproj │ │ │ │ │ └── project.pbxproj │ │ │ ├── xg-demo │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ ├── xg-framework-ext │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ ├── xg-shared-3.7 │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ ├── xg-shared-ext │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ ├── xg-static-3.7 │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── build.sh │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ └── xg-static-ext │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── build.sh │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ └── tests │ │ │ ├── Makefile │ │ │ ├── _old │ │ │ ├── py_call.c │ │ │ ├── test_corefoundation.c │ │ │ ├── test_goto.c │ │ │ ├── test_interactive.c │ │ │ ├── test_print.c │ │ │ └── test_string.c │ │ │ ├── _unused │ │ │ └── py_buffer_methods.c │ │ │ ├── build.sh │ │ │ ├── build_noxcode │ │ │ ├── test_build_noxcode.sh │ │ │ └── test_mxsdk.c │ │ │ ├── codecheck.sh │ │ │ ├── common.h │ │ │ ├── conftest.py │ │ │ ├── debug.sh │ │ │ ├── fourchar.py │ │ │ ├── installer.py │ │ │ ├── prelude │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── prelude.py │ │ │ └── test_prelude.py │ │ │ ├── py_handle_error_traceback.c │ │ │ ├── py_parser.py │ │ │ ├── python_cmake_buildsystem │ │ │ ├── Makefile │ │ │ ├── build.py │ │ │ ├── build.sh │ │ │ └── scproxy.patch │ │ │ ├── test_args.c │ │ │ ├── test_args_fail.c │ │ │ ├── test_build_embed_api.sh │ │ │ ├── test_call.c │ │ │ ├── test_call.py │ │ │ ├── test_clip_assign.c │ │ │ ├── test_cwd.c │ │ │ ├── test_demo.c │ │ │ ├── test_dict.py │ │ │ ├── test_dict_syntax.py │ │ │ ├── test_download_tar.py │ │ │ ├── test_generics.c │ │ │ ├── test_get_version.py │ │ │ ├── test_matrix_flattern.c │ │ │ ├── test_minim.c │ │ │ ├── test_modulegraph2.py │ │ │ ├── test_path_join.c │ │ │ ├── test_pipe.py │ │ │ ├── test_pthread.c │ │ │ ├── test_py.py │ │ │ ├── test_pyver.c │ │ │ ├── test_str_replace.c │ │ │ ├── test_to_dict.py │ │ │ ├── test_translate.c │ │ │ └── xlsx │ │ │ └── jit_matrix_analysis.xlsx │ ├── pyjs │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── TODO.md │ │ ├── pyjs.c │ │ └── pyjs.h │ ├── pymx │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── pymx.cpp │ ├── pyx │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── maxcpp │ │ │ ├── max.attr.h │ │ │ └── maxcpp6.h │ │ └── pyx.cpp │ ├── xpyc │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── services │ │ │ ├── PythonService.xcodeproj │ │ │ │ └── project.pbxproj │ │ │ └── PythonService │ │ │ │ ├── Info.plist │ │ │ │ ├── PythonService.entitlements │ │ │ │ └── main.c │ │ ├── tests │ │ │ ├── devnotes.md │ │ │ ├── server.c │ │ │ ├── test_pyservice │ │ │ │ ├── Makefile │ │ │ │ ├── main.c │ │ │ │ ├── project.xcconfig │ │ │ │ └── project.yml │ │ │ ├── test_python │ │ │ │ ├── build.sh │ │ │ │ └── test_python.c │ │ │ ├── test_server │ │ │ │ ├── build.sh │ │ │ │ └── server.c │ │ │ ├── test_xpc │ │ │ │ ├── README.md │ │ │ │ ├── test_xpc1 │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── xpc_client.c │ │ │ │ │ └── xpc_server.c │ │ │ │ ├── test_xpc2 │ │ │ │ │ ├── XPCService.xcodeproj │ │ │ │ │ │ └── project.pbxproj │ │ │ │ │ └── XPCService │ │ │ │ │ │ ├── Info.plist │ │ │ │ │ │ ├── XPCService.entitlements │ │ │ │ │ │ └── main.c │ │ │ │ └── xpc │ │ │ │ │ ├── activity.h │ │ │ │ │ ├── availability.h │ │ │ │ │ ├── base.h │ │ │ │ │ ├── connection.h │ │ │ │ │ ├── debug.h │ │ │ │ │ ├── endpoint.h │ │ │ │ │ ├── listener.h │ │ │ │ │ ├── rich_error.h │ │ │ │ │ ├── session.h │ │ │ │ │ └── xpc.h │ │ │ └── unused.c │ │ └── xpyc.c │ ├── zedit │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── mongoose.c │ │ ├── mongoose.h │ │ ├── n4m │ │ │ ├── Makefile │ │ │ ├── editor.mjs │ │ │ ├── help.html │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── css │ │ │ │ │ ├── normalize.css │ │ │ │ │ └── skeleton.css │ │ │ │ ├── help.html │ │ │ │ ├── images │ │ │ │ │ └── favicon.png │ │ │ │ ├── index.html │ │ │ │ └── robots.txt │ │ │ ├── rollup.config.mjs │ │ │ ├── zedit.js │ │ │ └── zedit.maxpat │ │ ├── web │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── editor.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── css │ │ │ │ │ ├── app.css │ │ │ │ │ ├── jquery.terminal.min.css │ │ │ │ │ ├── normalize.css │ │ │ │ │ ├── prism-terminal.css │ │ │ │ │ └── skeleton.css │ │ │ │ ├── images │ │ │ │ │ └── favicon.png │ │ │ │ ├── index.html │ │ │ │ ├── js │ │ │ │ │ ├── editor.min.js │ │ │ │ │ ├── jquery-3.3.1.min.js │ │ │ │ │ ├── jquery.terminal.min.js │ │ │ │ │ ├── prism-terminal.js │ │ │ │ │ └── prism.js │ │ │ │ └── robots.txt │ │ │ └── rollup.config.mjs │ │ ├── webroot │ │ └── zedit.c │ ├── zpy │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── tests │ │ │ └── test_server │ │ │ │ ├── build.sh │ │ │ │ └── server.c │ │ ├── zhelpers.h │ │ ├── zpy.c │ │ ├── zpy_client.py │ │ └── zpy_server.py │ └── ztp │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── server.py │ │ ├── tests │ │ ├── process │ │ │ ├── hello.py │ │ │ ├── hello.sh │ │ │ ├── run_cmds.c │ │ │ ├── test_spawn.c │ │ │ └── test_spawn2.c │ │ ├── safeeval.py │ │ └── threading │ │ │ ├── README.md │ │ │ ├── build.sh │ │ │ ├── test_thread1.c │ │ │ ├── test_thread2.c │ │ │ ├── test_thread3.c │ │ │ └── test_thread4.c │ │ └── ztp.c ├── scripts │ ├── api_ov.py │ ├── buildpy.py │ ├── cmake │ │ ├── common.cmake │ │ ├── fn_python3_external.cmake │ │ └── max-pretarget.cmake │ ├── install_leo.sh │ ├── maxref.py │ ├── py2max.py │ └── strip.py └── thirdparty │ ├── CMakeLists.txt │ ├── README.md │ ├── pocketpy │ ├── CMakeLists.txt │ ├── pocketpy.c │ └── pocketpy.h │ └── pybind11 │ ├── CMakeLists.txt │ ├── LICENSE │ ├── include │ └── pybind11 │ │ ├── attr.h │ │ ├── buffer_info.h │ │ ├── cast.h │ │ ├── chrono.h │ │ ├── common.h │ │ ├── complex.h │ │ ├── conduit │ │ ├── README.txt │ │ ├── pybind11_conduit_v1.h │ │ ├── pybind11_platform_abi_id.h │ │ └── wrap_include_python_h.h │ │ ├── detail │ │ ├── class.h │ │ ├── common.h │ │ ├── cpp_conduit.h │ │ ├── descr.h │ │ ├── dynamic_raw_ptr_cast_if_possible.h │ │ ├── exception_translation.h │ │ ├── function_record_pyobject.h │ │ ├── init.h │ │ ├── internals.h │ │ ├── native_enum_data.h │ │ ├── pybind11_namespace_macros.h │ │ ├── struct_smart_holder.h │ │ ├── type_caster_base.h │ │ ├── typeid.h │ │ ├── using_smart_holder.h │ │ └── value_and_holder.h │ │ ├── eigen.h │ │ ├── eigen │ │ ├── common.h │ │ ├── matrix.h │ │ └── tensor.h │ │ ├── embed.h │ │ ├── eval.h │ │ ├── functional.h │ │ ├── gil.h │ │ ├── gil_safe_call_once.h │ │ ├── gil_simple.h │ │ ├── iostream.h │ │ ├── native_enum.h │ │ ├── numpy.h │ │ ├── operators.h │ │ ├── options.h │ │ ├── pybind11.h │ │ ├── pytypes.h │ │ ├── stl.h │ │ ├── stl │ │ └── filesystem.h │ │ ├── stl_bind.h │ │ ├── trampoline_self_life_support.h │ │ ├── type_caster_pyobject_ptr.h │ │ ├── typing.h │ │ └── warnings.h │ ├── pybind11 │ ├── __init__.py │ ├── __main__.py │ ├── _version.py │ ├── commands.py │ ├── py.typed │ └── setup_helpers.py │ └── tools │ ├── FindCatch.cmake │ ├── FindEigen3.cmake │ ├── FindPythonLibsNew.cmake │ ├── JoinPaths.cmake │ ├── check-style.sh │ ├── cmake_uninstall.cmake.in │ ├── codespell_ignore_lines_from_errors.py │ ├── libsize.py │ ├── make_changelog.py │ ├── pybind11.pc.in │ ├── pybind11Common.cmake │ ├── pybind11Config.cmake.in │ ├── pybind11GuessPythonExtSuffix.cmake │ ├── pybind11NewTools.cmake │ ├── pybind11Tools.cmake │ ├── pyproject.toml │ ├── setup_global.py.in │ ├── setup_main.py.in │ └── test-pybind11GuessPythonExtSuffix.cmake └── support └── .keep /.gitignore: -------------------------------------------------------------------------------- 1 | # dirs, files, and patters to exclude 2 | **/project.xcworkspace 3 | **/xcshareddata 4 | **/xcuserdata 5 | *.dylib 6 | *.mxe 7 | *.mxe64 8 | *.mxo 9 | *.o 10 | *.opensdf 11 | *.pyc 12 | *.sdf 13 | *.sln 14 | *.suo 15 | workbook.leo 16 | .DS_Store 17 | .env 18 | .mypy_cache 19 | .pytest_cache 20 | .quarto 21 | .vs 22 | .vscode 23 | .venv 24 | __pycache__ 25 | build 26 | CMakeFiles 27 | env.sh 28 | externals/* 29 | extensions/* 30 | javascript/node_modules 31 | leoenv 32 | log.txt 33 | logs 34 | package-info.json 35 | source/projects/py/dump.yml 36 | source/projects/py/scripts/archive/* 37 | support/* 38 | sysbuild 39 | tmp 40 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "source/max-sdk-base"] 2 | path = source/max-sdk-base 3 | url = https://github.com/Cycling74/max-sdk-base.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Shakeeb Alireza 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | - [ ] Try pyodide in the browser to communicate with Max via the external / 4 | mongoose websockets. 5 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | 2 | Place python files with unique names in this folder (any directory structure is fine) and then send `[load ]` and`[read ]` messages to the `[py]` or `[pyjs]` objects or variants. 3 | 4 | -------------------------------------------------------------------------------- /examples/demos/hello.py: -------------------------------------------------------------------------------- 1 | # hello.py 2 | """This is a scratch pad of a python script in the `py` package.""" 3 | 4 | # basic examples 5 | a = 10 6 | 7 | b = 1.5 8 | 9 | c = "HELLO WORLD!!!" 10 | 11 | d = [1, 2, 3, 4] 12 | 13 | e = ["a", "b", "c"] 14 | 15 | f = lambda: "hello func" 16 | 17 | g = lambda x: x + 10 18 | 19 | h = '"a"' 20 | 21 | e = '"double-quoted"' 22 | 23 | f = "'single-quoted'" 24 | 25 | g = """a multiline lines 26 | of text. 27 | here. 28 | """ 29 | 30 | h = [b"10121", b"abcdef"] 31 | -------------------------------------------------------------------------------- /examples/servers/README.md: -------------------------------------------------------------------------------- 1 | # servers 2 | 3 | These are python files which are meant be run as a separate process by the `ztp` external. 4 | 5 | - `pyserver.py`: provides python interpreter service 6 | -------------------------------------------------------------------------------- /examples/tests/test_api_atomarray.py: -------------------------------------------------------------------------------- 1 | import api 2 | -------------------------------------------------------------------------------- /examples/tests/test_api_atombuf.py: -------------------------------------------------------------------------------- 1 | import api 2 | 3 | 4 | def test_atombuf_init(): 5 | buf = api.Atombuf("abc", 1, 1.5) 6 | api.bang_success() 7 | 8 | 9 | def test_atombuf_add_text(): 10 | buf = api.Atombuf.new() 11 | buf.add_text("#N buffer~ buf drumLoop.aif") 12 | return buf.to_text() 13 | 14 | 15 | def test_atombuf_to_text(): 16 | buf = api.Atombuf.new() 17 | buf.add_text("#N buffer~ buf drumLoop.aif") 18 | return buf.to_text() 19 | # api.post(buf.to_text()) 20 | 21 | 22 | def test_atombuf_to_list(): 23 | buf = api.Atombuf.new() 24 | buf.add_text("#N buffer~ buf drumLoop.aif") 25 | return buf.to_text() 26 | # api.post(str(buf.to_list())) 27 | -------------------------------------------------------------------------------- /examples/tests/test_api_database.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import api 4 | 5 | 6 | def test_db_init(): 7 | db_path = Path("/tmp/test_db.sqlite3") 8 | db = api.Database("mydb", str(db_path)) 9 | db.open() 10 | db.close() 11 | assert db_path.exists() 12 | 13 | 14 | def test_db_result(): 15 | db_path = Path("/tmp/test_db.sqlite3") 16 | db = api.Database("mydb", str(db_path)) 17 | db.open() 18 | db.query_table_new("mytable") 19 | result = db.query_direct("SELECT * FROM mytable") 20 | assert result.numrecords() == 0 21 | db.close() 22 | 23 | 24 | def test_db_view(): 25 | db_path = Path("/tmp/test_db.sqlite3") 26 | db = api.Database("mydb", str(db_path)) 27 | db.open() 28 | db.query_table_new("mytable") 29 | view = db.view_create("SELECT * FROM mytable") 30 | assert view.sql == "SELECT * FROM mytable" 31 | db.close() 32 | 33 | 34 | def test_db_view_result(): 35 | db_path = Path("/tmp/test_db.sqlite3") 36 | db = api.Database("mydb", str(db_path)) 37 | db.open() 38 | db.query_table_new("mytable") 39 | view = db.view_create("SELECT * FROM mytable") 40 | result = view.getresult() 41 | assert result.numrecords() == 0 42 | db.close() 43 | -------------------------------------------------------------------------------- /examples/tests/test_api_functions.py: -------------------------------------------------------------------------------- 1 | # tests top-level api functions only 2 | 3 | import api 4 | 5 | 6 | def test_bang(): 7 | api.bang() 8 | 9 | 10 | def success_bang(): 11 | api.success_bang() 12 | 13 | 14 | def failure_bang(): 15 | api.failure_bang() 16 | 17 | 18 | def test_out_sym(): 19 | api.out("hello outlet!") 20 | 21 | 22 | def test_out_int(): 23 | api.out(100) 24 | 25 | 26 | def test_out_float(): 27 | api.out(12.75) 28 | 29 | 30 | def test_out_list(): 31 | api.out([1, "a", "c", 4, 5]) 32 | 33 | 34 | def test_out_dict(): 35 | api.out({"a": [1, 2, "a"], "b": 1.3, "c": 100, "d": "e"}) 36 | 37 | 38 | def test_api_send(): 39 | api.send("intobj", 100) 40 | 41 | 42 | def test_lookup(): 43 | api.lookup("mrfloat") 44 | 45 | 46 | def test_post(): 47 | api.post("something post") 48 | 49 | 50 | def test_error(): 51 | api.error("an error") 52 | -------------------------------------------------------------------------------- /examples/tests/test_api_linklist.py: -------------------------------------------------------------------------------- 1 | import api 2 | 3 | # placeholder 4 | -------------------------------------------------------------------------------- /examples/tests/test_api_max.py: -------------------------------------------------------------------------------- 1 | # https://docs.cycling74.com/max8/vignettes/messages_to_max#Sending_a_message_to_the_Max_application 2 | 3 | import api 4 | 5 | mem = {} 6 | 7 | 8 | def test_max_init(): 9 | mem["m"] = api.Max() 10 | 11 | 12 | def test_max_midilist(): 13 | app = mem["m"] 14 | app.midilist() 15 | 16 | 17 | def test_max_clean(): 18 | app = mem["m"] 19 | app.clean() 20 | 21 | 22 | def test_max_maxwindow(): 23 | app = mem["m"] 24 | app.maxwindow() 25 | 26 | 27 | def test_max_clearmaxwindow(): 28 | app = mem["m"] 29 | app.clearmaxwindow() 30 | 31 | 32 | def test_max_paths(): 33 | app = mem["m"] 34 | app.paths() 35 | 36 | 37 | def test_max_externaleditor(): 38 | app = mem["m"] 39 | app.externaleditor("Sublime Text.app") 40 | -------------------------------------------------------------------------------- /examples/tests/test_api_perf.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import api 4 | 5 | 6 | def benchmark1(): 7 | LOOP_ITERATIONS = 1000 8 | ARRAY_SIZE = 4096 9 | 10 | data = [] 11 | for i in range(ARRAY_SIZE): 12 | data.append(74) 13 | 14 | api.post("starting benchmark1") 15 | starttime = time.time() 16 | val = 0 17 | 18 | for i in range(LOOP_ITERATIONS): 19 | for j in range(ARRAY_SIZE): 20 | val += data[j] 21 | 22 | elapsedtime = round((time.time() - starttime) * 1000) # ms 23 | api.post(f"benchmark results: {LOOP_ITERATIONS} iterations in {elapsedtime} ms") 24 | api.post(f"arrray accumulation is: {val}") 25 | api.post("compare with js in 170ms and v8 in 27ms (pre-jit)") 26 | -------------------------------------------------------------------------------- /examples/tests/test_api_pyexternal.py: -------------------------------------------------------------------------------- 1 | import api 2 | 3 | mem = {} 4 | 5 | 6 | def test_pyexternal_init(): 7 | ext = mem["ext"] = api.PyExternal() 8 | ext.out(f"{ext.name} external is initialized") 9 | 10 | 11 | def test_pyexternal_bang(): 12 | ext = mem["ext"] 13 | ext.bang() 14 | 15 | 16 | def test_pyexternal_bang_success(): 17 | ext = mem["ext"] 18 | ext.bang_success() 19 | 20 | 21 | def test_pyexternal_bang_failure(): 22 | ext = mem["ext"] 23 | ext.bang_failure() 24 | 25 | 26 | def test_pyexternal_box(): 27 | ext = mem["ext"] 28 | box = ext.get_box() 29 | ext.log_info(f"rec: {box.get_patching_rect()}") 30 | 31 | 32 | def test_pyexternal_patcher(): 33 | ext = mem["ext"] 34 | p = ext.get_patcher() 35 | return p.filename 36 | 37 | 38 | def test_pyexternal_scan(): 39 | ext = mem["ext"] 40 | ext.scan() 41 | 42 | 43 | def test_pyexternal_lookup(): 44 | ext = mem["ext"] 45 | ext.lookup("abc") 46 | 47 | 48 | def test_pyexternal_send(): 49 | ext = mem["ext"] 50 | ext.send("abc", 100) 51 | -------------------------------------------------------------------------------- /examples/tests/test_functional.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Iterable 2 | 3 | 4 | # some helpers 5 | 6 | 7 | def flatten(items): 8 | """Yield items from any nested iterable; see Reference. 9 | 10 | see: https://stackoverflow.com/questions/952914/how-do-i-make-a-flat-list-out-of-a-list-of-lists 11 | """ 12 | for x in items: 13 | if isinstance(x, Iterable) and not isinstance(x, (str, bytes)): 14 | for sub_x in flatten(x): 15 | yield sub_x 16 | else: 17 | yield x 18 | 19 | 20 | # some test functions 21 | 22 | identity = lambda x: x 23 | 24 | add = lambda x, y: x + y 25 | 26 | product = lambda x, y: x * y 27 | 28 | add100 = lambda x: x + 100 29 | 30 | sub20 = lambda x: x - 20 31 | 32 | div2 = lambda x: x / 2 33 | 34 | mul2 = lambda x: x * 2 35 | 36 | mul10 = lambda x: x * 10 37 | 38 | mul5 = lambda x: x * 5 39 | 40 | mul6 = lambda x: x * 7 41 | 42 | sumargs = lambda *args, **kwargs: sum(args) 43 | 44 | sumvals = lambda *args, **kwargs: sum(v for (k, v) in kwargs.items()) 45 | 46 | 47 | def func1(*args, **kwds): 48 | return "{}({} {})".format(func1.__name__, str(args), str(kwds)) 49 | 50 | 51 | def func2(*args, **kwds): 52 | return sum(args) + len(kwds.items()) 53 | -------------------------------------------------------------------------------- /help/zpy.maxhelp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/help/zpy.maxhelp -------------------------------------------------------------------------------- /init/py-fileformats.txt: -------------------------------------------------------------------------------- 1 | max definekind python @parent textfile @showextension 1; 2 | max fileformat .py TEXT 0 "Python Source file" python; 3 | -------------------------------------------------------------------------------- /javascript/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.0", 9 | "license": "ISC", 10 | "dependencies": { 11 | "python-shell": "^3.0.1" 12 | } 13 | }, 14 | "node_modules/python-shell": { 15 | "version": "3.0.1", 16 | "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-3.0.1.tgz", 17 | "integrity": "sha512-TWeotuxe1auhXa5bGRScxnc2J+0r41NBntSa6RYZtMBLtAEsvCboKrEbW6DvASosWQepVkhZZlT3B5Ei766G+Q==", 18 | "engines": { 19 | "node": ">=0.10" 20 | } 21 | } 22 | }, 23 | "dependencies": { 24 | "python-shell": { 25 | "version": "3.0.1", 26 | "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-3.0.1.tgz", 27 | "integrity": "sha512-TWeotuxe1auhXa5bGRScxnc2J+0r41NBntSa6RYZtMBLtAEsvCboKrEbW6DvASosWQepVkhZZlT3B5Ei766G+Q==" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript", 3 | "version": "1.0.0", 4 | "main": "pynode.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "python-shell": "^3.0.1" 13 | }, 14 | "description": "" 15 | } 16 | -------------------------------------------------------------------------------- /javascript/test_pynode.py: -------------------------------------------------------------------------------- 1 | 2 | print("HELLO WORLD") 3 | 4 | -------------------------------------------------------------------------------- /jsextensions/maxclasswrap.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Wraps the pyjs external for use by the js object in max 4 | 5 | */ 6 | 7 | maxclasswrap("pyjs","PyJS"); 8 | 9 | -------------------------------------------------------------------------------- /media/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/media/.keep -------------------------------------------------------------------------------- /media/py-maxhelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/media/py-maxhelp.png -------------------------------------------------------------------------------- /media/xkcd-python-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/media/xkcd-python-environment.png -------------------------------------------------------------------------------- /patchers/README.md: -------------------------------------------------------------------------------- 1 | A place of `py-js` related patcher files. 2 | 3 | Note that `py_overview.maxpat` and `pyjs_overview.maxpat` are now the 4 | corresponding help files for the respective objects. 5 | 6 | 7 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_jweb/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

A demo of interaction between jweb and max

7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_jweb/demo.js: -------------------------------------------------------------------------------- 1 | // demo.js 2 | 3 | window.max.bindInlet('say_hello', function() { 4 | const greeting = "hello world!!!"; 5 | alert(`we say: ${greeting}`); 6 | }); 7 | 8 | window.max.bindInlet('out', function (a) { 9 | // output a string 10 | // window.max.outlet(a); 11 | 12 | // output a list 13 | window.max.outlet(a, 1, 2); 14 | 15 | // output contents of array with prepended 'foo' message 16 | var ar = [1, 2, 3, 4]; 17 | // window.max.outlet.apply(window.max, ['foo'].concat(ar)); 18 | }); 19 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_pyscript/code.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | 16 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_pyscript/complex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Let's plot random numbers

9 |
10 | 11 | { 12 | "packages": ["numpy", "matplotlib"] 13 | } 14 | 15 | 16 | import matplotlib.pyplot as plt 17 | import numpy as np 18 | x = np.random.randn(1000) 19 | y = np.random.randn(1000) 20 | fig, ax = plt.subplots() 21 | ax.scatter(x, y) 22 | display(fig, target="plot") 23 | 24 | 25 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_pyscript/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_pyscript/run_server.sh: -------------------------------------------------------------------------------- 1 | npx static-handler --coi . 2 | 3 | -------------------------------------------------------------------------------- /patchers/tests/test_py_web/test_pyscript/utils.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime as dt 2 | 3 | 4 | def format_date(dt_, fmt="%m/%d/%Y, %H:%M:%S"): 5 | return f"{dt_:{fmt}}" 6 | 7 | 8 | def now(fmt="%m/%d/%Y, %H:%M:%S"): 9 | return format_date(dt.now(), fmt) 10 | 11 | 12 | def remove_class(element, class_name): 13 | element.element.classList.remove(class_name) 14 | 15 | 16 | def add_class(element, class_name): 17 | element.element.classList.add(class_name) 18 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cython 2 | -------------------------------------------------------------------------------- /source/demos/README.md: -------------------------------------------------------------------------------- 1 | # demos folder 2 | 3 | This folder serves as a place for testing ideas and prototyping external implementations. 4 | 5 | ## Building 6 | 7 | ```sh 8 | make demos 9 | ``` 10 | -------------------------------------------------------------------------------- /source/demos/cmx/README.md: -------------------------------------------------------------------------------- 1 | # libcmx: common max library 2 | 3 | This project is created as a common library of general functions which may be useful in Max externals and which can be used across projects. 4 | 5 | It's implemented as a single header library and has only a dependency on `max-sdk-base`. 6 | 7 | There are no projects currently using it except the `demo` scratchpad, but it may be use in a future refactoring effort. 8 | -------------------------------------------------------------------------------- /source/demos/cmx/cmx.c: -------------------------------------------------------------------------------- 1 | 2 | #define CMX_IMPLEMENTATION 3 | #include "cmx.h" 4 | 5 | /** 6 | * empty file to facilitate compilation as static lib 7 | */ 8 | -------------------------------------------------------------------------------- /source/demos/cmx/cmx.cpp: -------------------------------------------------------------------------------- 1 | #define CMX_IMPLEMENTATION 2 | #include "cmx.h" 3 | 4 | /** 5 | * empty file to facilitate compilation as static lib 6 | */ 7 | -------------------------------------------------------------------------------- /source/demos/demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | 5 | ############################################################# 6 | # MAX EXTERNAL 7 | ############################################################# 8 | 9 | include_directories( 10 | "${MAX_SDK_INCLUDES}" 11 | "${MAX_SDK_MSP_INCLUDES}" 12 | "${MAX_SDK_JIT_INCLUDES}" 13 | ) 14 | 15 | file(GLOB PROJECT_SRC 16 | "*.h" 17 | "*.c" 18 | "*.cpp" 19 | ) 20 | 21 | 22 | add_library( 23 | ${PROJECT_NAME} 24 | MODULE 25 | ${PROJECT_SRC} 26 | ) 27 | 28 | 29 | target_link_libraries( 30 | ${PROJECT_NAME} 31 | PRIVATE 32 | cmx 33 | ) 34 | 35 | 36 | # target_include_directories(${PROJECT_NAME} PRIVATE 37 | # ${CMAKE_SOURCE_DIR}/source/projects/cmx 38 | # ) 39 | 40 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 41 | -------------------------------------------------------------------------------- /source/demos/demo/README.md: -------------------------------------------------------------------------------- 1 | # demo 2 | 3 | This is a just scratchpad project for testing random things. It's not important. 4 | -------------------------------------------------------------------------------- /source/demos/mx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/max-pretarget.cmake) 2 | 3 | ############################################################# 4 | # MAX EXTERNAL 5 | ############################################################# 6 | 7 | include_directories( 8 | "${MAX_SDK_INCLUDES}" 9 | "${MAX_SDK_MSP_INCLUDES}" 10 | "${MAX_SDK_JIT_INCLUDES}" 11 | ) 12 | 13 | file(GLOB PROJECT_SRC 14 | "*.h" 15 | "*.c" 16 | "*.cpp" 17 | ) 18 | 19 | add_library( 20 | ${PROJECT_NAME} 21 | MODULE 22 | ${PROJECT_SRC} 23 | ) 24 | 25 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 26 | -------------------------------------------------------------------------------- /source/demos/mx/README.md: -------------------------------------------------------------------------------- 1 | # mx: minimal test case 2 | 3 | Based on max-sdk's `simplemax`, this is a template for throwaway prototypes of max externals. 4 | -------------------------------------------------------------------------------- /source/docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.quarto/ 2 | leoenv 3 | 4 | -------------------------------------------------------------------------------- /source/docs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | .PHONY: all update build pdf clean 4 | 5 | all: build 6 | 7 | update: 8 | @./scripts/update.py 9 | 10 | build: update pdf 11 | @echo "Update and PDF build complete." 12 | 13 | pdf: 14 | @quarto render --to pdf 15 | 16 | clean: 17 | @rm -rf .quarto _book 18 | @find . \( -name '*.aux' -o -name '*.log' -o -name '*.pdf' -o -name '*.tex' -o -name '*.toc' \) -delete 19 | -------------------------------------------------------------------------------- /source/docs/README.md: -------------------------------------------------------------------------------- 1 | # About this section 2 | 3 | This is documentation section intended to be used to consolidate and organize all project documentation and notes into a user/dev guide. 4 | 5 | The 'guide' is being developed using [quarto](https://quarto.org), an open-source scientific and technical publishing system and [leo-editor](https://leo-editor.github.io/leo-editor/) a programmable outline-based editor with literate programming features. 6 | 7 | ## Outline editing 8 | 9 | The outline of the book can be edited in outline by [leo-editor](https://leo-editor.github.io/leo-editor), the `workbook.leo` document just contains references to the documents and does not contain them. 10 | 11 | Leo `v6.7.7` is used in this case. 12 | 13 | 14 | ## Idiosyncrasies 15 | 16 | Quarto can fail: 17 | 18 | - if a bibliographic reference is not used! 19 | 20 | ```latex 21 | updating existing packages 22 | ERROR: 23 | compilation failed- error 24 | LaTeX Error: Something's wrong--perhaps a missing \item. 25 | 26 | See the LaTeX manual or LaTeX Companion for explanation. 27 | Type H for immediate help. 28 | ... 29 | 30 | l.1806 \end{CSLReferences} 31 | ``` 32 | -------------------------------------------------------------------------------- /source/docs/_archive/intro.qmd: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This is a book created from markdown and executable code. 4 | 5 | See @knuth84 for additional discussion of literate programming. 6 | 7 | 8 | 9 | ## r-based plot 10 | 11 | ```{r} 12 | #| label: fig-polar1 13 | #| echo: false 14 | #| fig-cap: "A line plot on a polar axis" 15 | plot(rnorm(1000, 0, 1)) 16 | ``` 17 | 18 | 19 | 20 | ## python-based plot 21 | 22 | ```{python} 23 | #| label: fig-polar2 24 | #| echo: false 25 | #| warning: false 26 | #| fig-cap: "A curve" 27 | 28 | import matplotlib.pyplot as plt 29 | import numpy as np 30 | 31 | x = np.arange(0.0, 2, 0.01) 32 | y1 = np.sin(2 * np.pi * x) 33 | y2 = 0.8 * np.sin(4 * np.pi * x) 34 | 35 | fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(6, 6)) 36 | 37 | ax1.fill_between(x, y1) 38 | ax1.set_title('fill between y1 and 0') 39 | 40 | ax2.fill_between(x, y1, 1) 41 | ax2.set_title('fill between y1 and 1') 42 | 43 | ax3.fill_between(x, y1, y2) 44 | ax3.set_title('fill between y1 and y2') 45 | ax3.set_xlabel('x') 46 | fig.tight_layout() 47 | plt.show() 48 | ``` 49 | -------------------------------------------------------------------------------- /source/docs/_book/Python3-Externals-for-Max-MSP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/_book/Python3-Externals-for-Max-MSP.pdf -------------------------------------------------------------------------------- /source/docs/index.qmd: -------------------------------------------------------------------------------- 1 | # Preface {.unnumbered} 2 | 3 | This is a Quarto book. 4 | 5 | To learn more about Quarto books visit . 6 | -------------------------------------------------------------------------------- /source/docs/src/dev/build-times.txt: -------------------------------------------------------------------------------- 1 | make default 3.58s user 0.84s system 66% cpu 6.623 total 2 | make framework-ext 736.81s user 70.47s system 98% cpu 13:35.52 total 3 | make framework-pkg 758.27s user 78.94s system 99% cpu 14:05.06 total 4 | make homebrew-ext 2.22s user 1.80s system 61% cpu 6.561 total 5 | make homebrew-pkg 2.26s user 3.50s system 68% cpu 8.443 total 6 | make shared-ext 757.44s user 72.90s system 98% cpu 13:59.00 total 7 | make shared-pkg 771.23s user 73.14s system 98% cpu 14:15.28 total 8 | make static-ext 1061.85s user 75.18s system 88% cpu 21:20.65 total 9 | make tiny-static-ext 878.85s user 67.33s system 88% cpu 17:46.19 total -------------------------------------------------------------------------------- /source/docs/src/dev/builder/build-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/builder/build-graph.png -------------------------------------------------------------------------------- /source/docs/src/dev/builder/building-on-apple-silicon.qmd: -------------------------------------------------------------------------------- 1 | # Building py-js externals on Apple Silicon 2 | 3 | 4 | ## Dev Notes 5 | 6 | - current main branch works after shift to `max-base-sdk` 7 | - build variation tested successfully so far: `framework-ext` 8 | 9 | ## What I did 10 | 11 | - used `framework-ext` 12 | 13 | - Changed `configure` of `FrameworkPythonBuilder` to include 14 | `--with-universal-archs=universal2` but did **NOT** include `--enable-universalsdk` 15 | 16 | - The `Python.framework` was consequently built as a native framework 17 | 18 | - After trying to run in xcode, there were some linking errors. 19 | 20 | - Had to change the `py-js.xcconfig` of `framework-ext` or the configuration in XCODE such that 21 | 22 | ```text 23 | // added $(PYJS_BUILD_LIB) to FRAMEWORK_SEARCH_PATH 24 | // Did this directly via xcode but you can 25 | // add it to `py-js.xcconfig` 26 | 27 | FRAMEWORK_SEARCH_PATH = $(inherited) $(PYJS_BUILD_LIB) 28 | ``` 29 | 30 | - Changed the target architecture to `arm64` 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /source/docs/src/dev/builder/fix_arm64_bug.qmd: -------------------------------------------------------------------------------- 1 | from: https://developer.apple.com/forums/thread/696281 2 | 3 | 4 | You should rather link with the framework provided by your installed version of Python3. 5 | 6 | Locate your installation of Python3 by using this command in Terminal: 7 | 8 | ls -la $(which python3) 9 | 10 | The framework is in the "Frameworks" folder located one level above "bin", 11 | for example: `/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks` 12 | 13 | Once your have the location of the Python3 framework, add it as a framework in your XCode project. In the Build Settings, don't forget to add: 14 | 15 | 1. the Frameworks folder location in Framework Search Path (e.g. "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks") 16 | 17 | 2. the framework's Headers folder in Header Search Path (e.g. "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Headers") 18 | 19 | 20 | -------------------------------------------------------------------------------- /source/docs/src/dev/builder/make-dmg.qmd: -------------------------------------------------------------------------------- 1 | # Make, Sign and Notarize DMGs 2 | 3 | ## Helpful Articles 4 | 5 | - [Creating Distribution-Signed Code for Mac](https://developer.apple.com/forums/thread/701514#701514021) 6 | 7 | - [Packaging Mac Software for Distribution](https://developer.apple.com/forums/thread/701581#701581021) 8 | 9 | - [Customizing the Notarization Workflow](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow?language=objc) 10 | 11 | - [https://developer.apple.com/forums/thread/130560](https://developer.apple.com/forums/thread/130560) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /source/docs/src/dev/builder/matrix.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/builder/matrix.xlsx -------------------------------------------------------------------------------- /source/docs/src/dev/builder/remove-detritus.qmd: -------------------------------------------------------------------------------- 1 | # remove detritus 2 | 3 | To remove detritus, please the following in the final script added to xcode build phases: 4 | 5 | ```bash 6 | xattr -cr $HOME/Library/Developer/Xcode/DerivedData || echo Clear 7 | xattr -cr "$PROJECT_DIR" || echo Clear 8 | ``` 9 | 10 | -------------------------------------------------------------------------------- /source/docs/src/dev/builder/switching-between-modes.qmd: -------------------------------------------------------------------------------- 1 | # Switching between Modes 2 | 3 | 4 | ## Mode A: `py-js` symlinked to `$HOME/Documents/Max 8/Packages/py-js` 5 | 6 | 7 | Ensure that py-js is not in a path with a space in it. 8 | 9 | ```bash 10 | core.project.is_symlinked = True 11 | 12 | py-js/source/py/targets/common.xcconfig 13 | PYJS_BUILD_ROOT = $(SRCROOT)/../build 14 | DSTROOT = $(SRCROOT)/../../../externals (default) 15 | 16 | ``` 17 | 18 | subdependencies are built in `py-js/source/py/targets/build/lib` 19 | 20 | 21 | 22 | ## Mode B: `py-js` copied to `$HOME/Documents/Max 8/Packages/py-js` 23 | 24 | 25 | ```bash 26 | core.project.is_symlinked = False 27 | 28 | py-js/source/py/targets/common.xcconfig 29 | PYJS_BUILD_ROOT = $(HOME)/.build_pyjs 30 | DSTROOT = $(PYJS_BUILD_ROOT)/externals 31 | 32 | ``` 33 | 34 | subdependencies are built in `$HOME/.build_pyjs/lib` 35 | 36 | targets which are affected: 37 | 38 | - `framework-ext` (location of `Python.framework`) changes between modes 39 | - `shared-ext`: `lib` from `python-shared` 40 | - `static-ext`: `lib` from `python-static` -------------------------------------------------------------------------------- /source/docs/src/dev/devguide.qmd: -------------------------------------------------------------------------------- 1 | # Guide to Developers 2 | 3 | 4 | ## Code Style 5 | 6 | The coding style for this project can be applied automatically during the build process with `clang-format`. On OS X, you can easily install this using brew: 7 | 8 | ```bash 9 | brew install clang-format 10 | ``` 11 | 12 | The style used in this project is specified in the `.clang-format` file. 13 | 14 | 15 | -------------------------------------------------------------------------------- /source/docs/src/dev/general/xcodebuild.md: -------------------------------------------------------------------------------- 1 | # xcodebuild 2 | 3 | To set output of product use `BUILD_DIR` and `SYMROOT` for object dir 4 | 5 | For example 6 | 7 | ```sh 8 | xcodebuild \ 9 | -arch arm64 \ 10 | -project PythonService.xcodeproj \ 11 | SYMROOT=$(HOME)/projects/py-js/build/python_service \ 12 | BUILD_DIR=$(HOME)/projects/py-js/build 13 | 14 | xcodebuild 15 | -project 16 | -exportPath 20 | -destination 21 | -arch 22 | -target NAME 23 | BUILD_DIR=~/projects/py-js/build 24 | 25 | xcodebuild -arch arm64 -project PythonService.xcodeproj 26 | 27 | ``` -------------------------------------------------------------------------------- /source/docs/src/dev/py/build-options.qmd: -------------------------------------------------------------------------------- 1 | # Build or Config Options 2 | 3 | ## Use Flags? 4 | 5 | ```c 6 | /*--------------------------------------------------------------------------*/ 7 | /* Options */ 8 | 9 | typedef enum 10 | { 11 | FLAG1 = 1 << 0, // 1 12 | FLAG2 = 1 << 1, // 2 13 | FLAG3 = 1 << 2, // 4 14 | FLAG4 = 1 << 3, // 8 15 | FLAG5 = 1 << 4, // 16 16 | FLAG6 = 1 << 5, // 32 17 | FLAG7 = 1 << 6, // 64 18 | FLAG8 = 1 << 7 // 128 19 | } PY_CFG_FLAGS; 20 | ``` 21 | 22 | No flags set: 23 | 24 | ```c 25 | unsigned int flag_opts = 0; 26 | 27 | ``` 28 | 29 | setting flags 30 | 31 | ```c 32 | flag_opts |= FLAG2; 33 | ``` 34 | 35 | or 36 | 37 | ```c 38 | flag_opts = FLAG1 | FLAG2 | FLAG8; 39 | ``` 40 | 41 | checking if flags are set 42 | 43 | ```c 44 | if(flag_opts & FLAGN) 45 | 46 | ``` 47 | 48 | refs: 49 | 50 | - 51 | 52 | - 53 | 54 | 55 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/dont.qmd: -------------------------------------------------------------------------------- 1 | # Don't Do This 2 | 3 | ## Don't 4 | 5 | - Don't give attributes the same name as methods (the `import` saga) as this cause problems and crashes. Fixed by making them different. 6 | 7 | - Don't put a space in `eval` expressions without quoting the whole 8 | 9 | - Don't put a space in path causes "sprintf" type debugging in execfile to crash max! 10 | 11 | - Don't develop in Package in Documents/... this causes issues due to icloud syncing. 12 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/experiments.qmd: -------------------------------------------------------------------------------- 1 | # Experiments 2 | 3 | ## Trying to Compile the Max API wrapper as a python builtin 4 | 5 | To overcome the code-loading problem, tried to compile minimal version of `api.pyx` + `py_max.pxd` as a python builtin. 6 | 7 | The Setup.local file used is in `py-js/source/py/patch/3.9/setup-static-api.local` 8 | 9 | To get it to compile with python, I run `python3 -m builder py_static --download` to download `Python-X.Y.Z` as src, copied a minimal version of api.c which did not import the header from py.c to `Python-X.Y.Z/Modules` and then `make`. 10 | 11 | To compile with Xcode I had to add '-fprofile-instr-generate' to `Other Linker Flags` and used the `static_ext` recipe for static self-contained compilation of the external. 12 | 13 | **Outcome**: Managed to produce an external which worked as expected and was able to `import api`, but unfortunately embedding `api.c` in python as a statically compiled builtin did not fix the code loading issue. 14 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/python-shell-via-nodejs.qmd: -------------------------------------------------------------------------------- 1 | # python-shell: pynode 2 | 3 | 4 | 5 | ## Credit 6 | 7 | Idea and Script from TO_THE_SUN during discussion of python and max on the max forum (https://cycling74.com/forums/python-in-max-1) 8 | 9 | see: 10 | - [python-shall](https://www.npmjs.com/package/python-shell) 11 | - [python-shell rep](https://github.com/extrabacon/python-shell) 12 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/scripting-tips.qmd: -------------------------------------------------------------------------------- 1 | # Scripting Do's & Dont's 2 | 3 | Here are some tips when scripting max with python using the py external. This only applies to python 4 | 5 | ## Don't 6 | 7 | - redirect stdout and try to read from the python script. The following will crash Max: 8 | 9 | ```python 10 | # test stdout/stderr redirection 11 | sys.stdout = io.StringIO() 12 | print('foo') 13 | print('hello max!') 14 | api.post("from py: %s", sys.stdout.getvalue()) 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/snippets.qmd: -------------------------------------------------------------------------------- 1 | # Snippets 2 | 3 | ## Locate path from string 4 | 5 | - depends on specifying FOUR_CHAR_CODE 6 | 7 | ```c 8 | void py_locate_path_from_string(t_py* x, char* s) 9 | { 10 | char filename[MAX_PATH_CHARS]; 11 | char pathname[MAX_PATH_CHARS]; 12 | short path; 13 | t_fourcc type = FOUR_CHAR_CODE('TEXT'); 14 | t_filehandle fh; 15 | t_max_err err; 16 | 17 | strncpy_zero(filename, s, MAX_PATH_CHARS); 18 | if (locatefile_extended(filename, &path, &type, &type, 1)) { 19 | // nozero: not found 20 | py_error(x, "can't find file %s", s); 21 | return; 22 | } else { 23 | pathname[0] = 0; 24 | err = path_toabsolutesystempath(path, filename, pathname); 25 | if (err != MAX_ERR_NONE) { 26 | py_error(x, "can't convert %s to absolutepath", s); 27 | return; 28 | } 29 | py_log(x, "full path is: %s", pathname); 30 | } 31 | } 32 | ``` 33 | 34 | use it: 35 | 36 | ```c 37 | py_locate_path_from_string(x, "file.py"); 38 | ``` 39 | -------------------------------------------------------------------------------- /source/docs/src/dev/py/types.qmd: -------------------------------------------------------------------------------- 1 | # max datastructures 2 | 3 | 4 | 5 | ## t_dictionary and dictobject 6 | 7 | Some forum research on dictionary-passing-api 8 | 9 | - https://cycling74.com/forums/dictobj-expose-to-pattr 10 | - https://cycling74.com/forums/dictionary-with-key-value-entries-specified-by-sprintf-style-syntax-scripting 11 | - https://cycling74.com/forums/freeingclearing-a-dictionary-without-causing-memory-leaks 12 | - https://cycling74.com/forums/being-compatible-with-the-dictionary-passing-system-dict-object 13 | - https://cycling74.com/forums/dictionary-io-in-c-crashing-on-dictionary_getatom 14 | 15 | 16 | -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/javascript.qmd: -------------------------------------------------------------------------------- 1 | # Javascript 2 | 3 | ## Messages to local receive objects 4 | 5 | 6 | -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/@fridgerator-pynode - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/@fridgerator-pynode - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/@savearray2-py.js - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/@savearray2-py.js - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/Almenon-AREPL-vscode- program python in real-time.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/Almenon-AREPL-vscode- program python in real-time.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/Brython.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/Brython.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/CodeMirror.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/CodeMirror.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/Gottox-node-webterm- simple demo application for child_pty and terminal.js..webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/Gottox-node-webterm- simple demo application for child_pty and terminal.js..webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/arepl-backend - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/arepl-backend - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/awesome-react-repl - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/awesome-react-repl - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/brython - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/brython - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/eclipse-theia-theia- Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript..webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/eclipse-theia-theia- Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript..webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@aminya-jmp - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@aminya-jmp - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@jupyterlab-services - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@jupyterlab-services - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@nteract-kernel-relay - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@nteract-kernel-relay - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@nteract-messaging - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/@nteract-messaging - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/enchannel-zmq-backend - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/enchannel-zmq-backend - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/ipycallback - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/ipycallback - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/jmp-zeromq6 - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/jmp-zeromq6 - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/n-riesco-jmp- Node.js module for creating, parsing and replying to messages of the Jupyter Messaging….webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/jupyter/n-riesco-jmp- Node.js module for creating, parsing and replying to messages of the Jupyter Messaging….webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/pyconnector - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/pyconnector - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/python-bridge - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/python-bridge - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/python-shell - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/python-shell - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/terminal.js - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/terminal.js - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/dev/pyjs/pyjs-nodejs/zeromq - npm.webloc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/dev/pyjs/pyjs-nodejs/zeromq - npm.webloc -------------------------------------------------------------------------------- /source/docs/src/externals/cmx.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "libcmx: common max library" 3 | --- 4 | 5 | This project is created as a common library of general functions which may be useful in Max externals and which can be used across projects. 6 | 7 | It's implemented as a single header library and has only a dependency on `max-sdk-base`. 8 | 9 | There are no projects currently using it except the `demo` scratchpad, but it may be use in a future refactoring effort. 10 | -------------------------------------------------------------------------------- /source/docs/src/externals/demo.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "demo" 3 | --- 4 | 5 | This is a just scratchpad project for testing random things. It's not important. 6 | -------------------------------------------------------------------------------- /source/docs/src/externals/krait.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "krait: an ITM-based python evaluator" 3 | --- 4 | 5 | This project provide a proof-of-concept to defer the evaluation of a python function via Max's ITM-based sequencing. 6 | 7 | Note that it has a dependency on another subproject: it includes mamba's single header c library, `py.h`, to reduce boilerplate and provide python interpreter 'services'. 8 | 9 | ## Current Status 10 | 11 | Crashes on Python3.13 (this is under investigation) 12 | 13 | ## Building 14 | 15 | From the root of the `py-js` project 16 | 17 | ```bash 18 | make projects 19 | ``` 20 | 21 | This will build all subprojects, including `krait`, using the standard cmake buildsystem. 22 | 23 | ## Help 24 | 25 | See `krait.maxhelp` in `py-js/help` folder. 26 | -------------------------------------------------------------------------------- /source/docs/src/externals/mpy.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mpy: micropython external" 3 | --- 4 | 5 | A proof-of-concept which embeds micropython in a max external 6 | 7 | Currently only tested on macOS. 8 | 9 | Can be built using `-DBUILD_MICROPYTHON_EXTERNAL` which will default to local micropython code. If the option `-DFETCH_MICROPYTHON` is used cmake will try to build from git clone. 10 | 11 | Doesn't do anything now useful except prove that embedding micropytho in an external is possible.. Still a work-in-progress and will be developed further as one familiarizes oneself with the micropython c-api. 12 | -------------------------------------------------------------------------------- /source/docs/src/externals/mpyx.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mpyx: a single-header c++ python3 library for min-api max externals" 3 | --- 4 | 5 | This is a proof-of-concept external using a variant of the `py_interpreter.h` single-header c++ python3 library from the `cobra` project, called `mpy_interpreter.h`, which is compatible for use with [min-api](https://github.com/cycling74/min-api)-based projects. 6 | 7 | ## Usage 8 | 9 | This can be built individually with: 10 | 11 | ```sh 12 | make mpyx 13 | ``` 14 | 15 | For a relocatable dynamically-linked build 16 | 17 | ```sh 18 | make mpyx-shared 19 | ``` 20 | 21 | For a relocatable statically-linked build 22 | 23 | ```sh 24 | make mpyx-static 25 | ``` 26 | -------------------------------------------------------------------------------- /source/docs/src/externals/pktpy2.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "pktpy2: a pocketpy v2.0.x max external" 3 | --- 4 | 5 | This external embeds version `2.0.5` of [pocketpy](https://github.com/blueloveTH/pocketpy), a Python interpreter for game engines, in a Max external. It is called `pktpy2` to differentiate it from the `pktpy` external which is based on the version `1.4.6` of `pocketpy`. 6 | 7 | The major difference / benefit between v2 and v1 is that the lua-like c-api used in the v2 implementation makes the external a good deal smaller (572KB for v2 vs 1.3MB for v1 so far). 8 | 9 | -------------------------------------------------------------------------------- /source/docs/src/externals/pyx.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "pyx: example use of cobra with maxcpp" 3 | --- 4 | 5 | This is a proof-of-concept of using `cobra`, the single-header c++ python3 library for Max externals with Graham Wakefield's [maxcpp](https://github.com/grrrwaaa/maxcpp) (C++ templates for Max/MSP objects) 6 | 7 | ## Usage 8 | 9 | This can be built individually with: 10 | 11 | ```sh 12 | make pyx 13 | ``` 14 | 15 | For a relocatable dynamically-linked build 16 | 17 | ```sh 18 | make pyx-shared 19 | ``` 20 | 21 | For a relocatable statically-linked build 22 | 23 | ```sh 24 | make pyx-static 25 | ``` 26 | -------------------------------------------------------------------------------- /source/docs/src/externals/shell.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "shell" 3 | --- 4 | 5 | The shell max external is written and Copyright (c) 2013-2019 Jeremy Bernstein and Bill Orcutt 6 | 7 | The original github repo is 8 | 9 | It is included here for convenience and because it has an elegant implementation using threading and interprocess communication. 10 | 11 | The intent is to learn from this and perhaps incorporate some of the techniques in the python externals. 12 | 13 | ## Changes from original 14 | 15 | - change `sprintf` to `snprintf_zero` 16 | -------------------------------------------------------------------------------- /source/docs/src/externals/xpyc.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "xpyc: a max external which communicates with python3 via xpc" 3 | --- 4 | 5 | A proof-of-concept stage Max external which uses [xpc](https://developer.apple.com/documentation/xpc?language=objc), a "lightweight mechanism for basic interprocess communication", to connect to a separate python process via an xpc service. 6 | 7 | Works on MacOS only. 8 | 9 | ## Building 10 | 11 | ```sh 12 | make xpyc 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /source/docs/src/externals/zpy.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "zpy: python3 via zmq in max" 3 | --- 4 | 5 | A max external which uses `zmq` to connect to a separate python process 6 | 7 | The objective is to replicate what the `py` external does but using zmq. 8 | 9 | ## Requires 10 | 11 | ```bash 12 | brew install zmq 13 | ``` 14 | 15 | ## Status 16 | 17 | - [ ] proof-of-concept 18 | 19 | ## TODO 20 | 21 | - how to launch python server automatically and close it with the patch 22 | 23 | ## Alternatives 24 | 25 | - [ ] run as subprocess and read and write from stdin and stdout via a pipe 26 | 27 | ## Research 28 | 29 | - 30 | 31 | - 32 | -------------------------------------------------------------------------------- /source/docs/src/externals/ztp.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ztp: the zeromq + threads + python Max external" 3 | --- 4 | 5 | ```text 6 | ┌─────────────────────────────────────────────────┐ 7 | │┌───────────┐ ┌───────────┐│ 8 | ││ │ │python code││ 9 | ││ client │◀────────zeromq───────▶│ server ││ 10 | ││ │ │ (spawned) ││ 11 | │└───────────┘ └───────────┘│ 12 | │ ztp external │ 13 | └─────────────────────────────────────────────────┘ 14 | ``` 15 | 16 | The `ztp` external (the name refers to python, threads and zeromq) uses `zmq` with threading for non-blocking communication with a spawned python code interpretation server which evaluates and executes python code and sends back the result. 17 | 18 | The combination of threads, zeromq and remote process mgmt of the spawned server make this much more usable than `zpy`, an earlier effort which lacked threads and which suffered from blocking during communication with the server. 19 | 20 | ## Requires 21 | 22 | ```bash 23 | brew install zmq 24 | ``` 25 | 26 | ## Learnings 27 | 28 | - This works: one thread per zmq socket as per the zmq rules. 29 | -------------------------------------------------------------------------------- /source/docs/src/media/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/media/.keep -------------------------------------------------------------------------------- /source/docs/src/media/py-maxhelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/media/py-maxhelp.png -------------------------------------------------------------------------------- /source/docs/src/media/xkcd-python-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/docs/src/media/xkcd-python-environment.png -------------------------------------------------------------------------------- /source/docs/src/references.bib: -------------------------------------------------------------------------------- 1 | @article{knuth84, 2 | author = {Knuth, Donald E.}, 3 | title = {Literate Programming}, 4 | year = {1984}, 5 | issue_date = {May 1984}, 6 | publisher = {Oxford University Press, Inc.}, 7 | address = {USA}, 8 | volume = {27}, 9 | number = {2}, 10 | issn = {0010-4620}, 11 | url = {https://doi.org/10.1093/comjnl/27.2.97}, 12 | doi = {10.1093/comjnl/27.2.97}, 13 | journal = {Comput. J.}, 14 | month = may, 15 | pages = {97–111}, 16 | numpages = {15} 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /source/docs/src/references.qmd: -------------------------------------------------------------------------------- 1 | # References {.unnumbered} 2 | 3 | ::: {#refs} 4 | ::: 5 | -------------------------------------------------------------------------------- /source/min-api/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | tmp 3 | doc/doxyfile 4 | doc/html 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /source/min-api/Authors.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | Names should be added to this file with this pattern: 3 | 4 | For individuals: 5 | `Name ` 6 | 7 | For organizations: 8 | `Organization ` 9 | 10 | 11 | 12 | ``` 13 | Cycling '74 <*@cycling74.com> 14 | David Butler 15 | Trond Lossius 16 | ``` 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /source/min-api/License.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2018, The Min-API Authors. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /source/min-api/doc/GuideToDataspaces.md: -------------------------------------------------------------------------------- 1 | # Dataspaces and Units of Measurement 2 | 3 | Dataspaces for attributes are an out-growth from the Jamoma project and the paper at NIME or ICMC or somewhere... 4 | 5 | ## Spatial Units 6 | 7 | I'm sure that if you review the code for this dataspace you'll find oddities several places. The reason is because we are using non-standard mathematical conversions: 8 | 9 | - Cartesian coordinates: x to right, y forward, z upwards 10 | - Polar: Navigational system with 0 degrees to the north (forward), +90 to the east (right), -90 to the west (left) and 180 south (back). 11 | 12 | This makes the formulas for conversions between Cartesian and Polar different to what you'd expect in a maths class. 13 | 14 | -------------------------------------------------------------------------------- /source/min-api/include/c74_min.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @ingroup minapi 3 | /// @copyright Copyright 2018 The Min-API Authors. All rights reserved. 4 | /// @license Use of this source code is governed by the MIT License found in the License.md file. 5 | 6 | #pragma once 7 | 8 | #define C74_MIN_WITH_IMPLEMENTATION 9 | 10 | #include "c74_min_api.h" 11 | #include "c74_min_attribute_impl.h" 12 | #include "c74_min_buffer_impl.h" 13 | #include "c74_min_impl.h" 14 | 15 | // The use of __has_include on Windows requires VS version 15.3 which is not yet available 16 | // Alternatively defined C74_USE_MIN_LIB using CMake 17 | #if defined(C74_USE_MIN_LIB) 18 | #include "../../min-lib/include/c74_lib.h" 19 | #elif __has_include("../../min-lib/include/c74_lib.h") 20 | #include "../../min-lib/include/c74_lib.h" 21 | #endif 22 | 23 | #define UNUSED(x) ((void)x) 24 | 25 | #undef C74_MIN_WITH_IMPLEMENTATION 26 | -------------------------------------------------------------------------------- /source/min-api/include/c74_min_dataspace.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @ingroup minapi 3 | /// @copyright Copyright 2018 The Min-API Authors. All rights reserved. 4 | /// @license Use of this source code is governed by the MIT License found in the License.md file. 5 | 6 | #pragma once 7 | 8 | namespace c74::min::dataspace { 9 | 10 | const double k_gain_midi_power{ log(pow(10.0, 10.0 / 20.0)) / log(127.0 / 100.0) }; 11 | const double k_gain_midi_power_r{ 1.0 / k_gain_midi_power }; 12 | 13 | class dataspace_base 14 | { 15 | public: 16 | // TODO: error checking -- can we do a static_assert that both source and dest are defined in the same dataspace? 17 | template 18 | static inline number convert(const number x) 19 | { 20 | return dest_unit_type::from_neutral(source_unit_type::to_neutral(x)); 21 | } 22 | }; 23 | 24 | } // namespace c74::min::dataspace 25 | 26 | #include "c74_min_dataspace_gain.h" 27 | #include "c74_min_dataspace_none.h" 28 | #include "c74_min_dataspace_time.h" 29 | -------------------------------------------------------------------------------- /source/min-api/include/c74_min_dataspace_none.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @ingroup minapi 3 | /// @copyright Copyright 2018 The Min-API Authors. All rights reserved. 4 | /// @license Use of this source code is governed by the MIT License found in the License.md file. 5 | 6 | #pragma once 7 | 8 | namespace c74::min::dataspace { 9 | 10 | class none : public dataspace_base 11 | { 12 | public: 13 | // the neutral unit is always a pass-through... compiler inlining should make it a noop 14 | class nothing 15 | { 16 | friend class dataspace_base; 17 | 18 | static inline number to_neutral(const number input) 19 | { 20 | return input; 21 | } 22 | 23 | static inline number from_neutral(const number input) 24 | { 25 | return input; 26 | } 27 | }; 28 | }; 29 | 30 | } // namespace c74::min::dataspace 31 | -------------------------------------------------------------------------------- /source/min-api/include/murmur/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Murmur3.h" 3 | 4 | 5 | 6 | int main() 7 | { 8 | 9 | const uint32_t hash = std::integral_constant::value; 10 | 11 | 12 | std::cerr << hash << std::endl; 13 | 14 | assert(hash == 4291478129); 15 | 16 | 17 | 18 | constexpr uint32_t i = Murmur3_32("foo"); 19 | std::cerr << i << std::endl; 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/.gitignore: -------------------------------------------------------------------------------- 1 | *.ipch 2 | *.suo 3 | *.user 4 | *.sdf 5 | *.opensdf 6 | *.exe 7 | *.VC.db 8 | .vs/ 9 | tests/stabtest/msvc*/Debug/ 10 | tests/stabtest/msvc*/Release/ 11 | tests/stabtest/msvc*/obj/ 12 | tests/stabtest/msvc*/log.txt 13 | tests/stabtest/log.txt 14 | tests/unittests/msvc*/Debug/ 15 | tests/unittests/msvc*/Release/ 16 | tests/unittests/msvc*/obj/ 17 | tests/CDSChecker/model-checker/ 18 | benchmarks/msvc*/Debug/ 19 | benchmarks/msvc*/Release/ 20 | benchmarks/msvc*/obj/ 21 | test/ 22 | # Linux binaries 23 | benchmarks/benchmarks 24 | tests/stabtest/stabtest 25 | tests/unittests/unittests 26 | 27 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | project(readerwriterqueue VERSION 1.0.0) 3 | 4 | include(GNUInstallDirs) 5 | 6 | add_library(${PROJECT_NAME} INTERFACE) 7 | 8 | install(FILES atomicops.h readerwriterqueue.h LICENSE.md 9 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) 10 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/benchmarks/makefile: -------------------------------------------------------------------------------- 1 | # ©2014 Cameron Desrochers 2 | 3 | ifeq ($(OS),Windows_NT) 4 | EXT=.exe 5 | PLATFORM_OPTS=-static 6 | else 7 | EXT= 8 | UNAME_S := $(shell uname -s) 9 | ifeq ($(UNAME_S),Darwin) 10 | PLATFORM_OPTS= 11 | else 12 | PLATFORM_OPTS=-Wl,--no-as-needed -lrt 13 | endif 14 | endif 15 | 16 | default: benchmarks$(EXT) 17 | 18 | benchmarks$(EXT): bench.cpp ../readerwriterqueue.h ../atomicops.h ext/1024cores/spscqueue.h ext/folly/ProducerConsumerQueue.h ../tests/common/simplethread.h ../tests/common/simplethread.cpp systemtime.h systemtime.cpp makefile 19 | g++ -std=c++11 -Wpedantic -Wall -DNDEBUG -O3 -g bench.cpp ../tests/common/simplethread.cpp systemtime.cpp -o benchmarks$(EXT) -pthread $(PLATFORM_OPTS) 20 | 21 | run: benchmarks$(EXT) 22 | ./benchmarks$(EXT) 23 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/benchmarks/systemtime.h: -------------------------------------------------------------------------------- 1 | // ©2013-2014 Cameron Desrochers 2 | 3 | #pragma once 4 | 5 | #if defined(_WIN32) 6 | #define ST_WINDOWS 7 | #elif defined(__APPLE__) && defined(__MACH__) 8 | #define ST_APPLE 9 | #elif defined(__linux__) || defined(__FreeBSD__) || defined(BSD) 10 | #define ST_NIX 11 | #else 12 | #error "Unknown platform" 13 | #endif 14 | 15 | #if defined(ST_WINDOWS) 16 | namespace moodycamel { typedef unsigned long long SystemTime; } 17 | #elif defined(ST_APPLE) 18 | #include 19 | namespace moodycamel { typedef std::uint64_t SystemTime; } 20 | #elif defined(ST_NIX) 21 | #include 22 | namespace moodycamel { typedef timespec SystemTime; } 23 | #endif 24 | 25 | namespace moodycamel 26 | { 27 | void sleep(int milliseconds); 28 | 29 | SystemTime getSystemTime(); 30 | 31 | // Returns the delta time, in milliseconds 32 | double getTimeDelta(SystemTime start); 33 | } 34 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/tests/stabtest/makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | EXT=.exe 3 | PLATFORM_OPTS=-static 4 | PLATFORM_LD_OPTS=-Wl,--no-as-needed 5 | else 6 | UNAME_S := $(shell uname -s) 7 | ifeq ($(UNAME_S),Darwin) 8 | EXT= 9 | PLATFORM_OPTS= 10 | PLATFORM_LD_OPTS= 11 | else 12 | EXT= 13 | PLATFORM_OPTS= 14 | PLATFORM_LD_OPTS=-lrt -Wl,--no-as-needed 15 | endif 16 | endif 17 | 18 | default: stabtest$(EXT) 19 | 20 | stabtest$(EXT): stabtest.cpp ../../readerwriterqueue.h ../../atomicops.h ../common/simplethread.h ../common/simplethread.cpp makefile 21 | g++ $(PLATFORM_OPTS) -std=c++11 -Wsign-conversion -Wpedantic -Wall -DNDEBUG -O3 stabtest.cpp ../common/simplethread.cpp -o stabtest$(EXT) -pthread $(PLATFORM_LD_OPTS) 22 | 23 | run: stabtest$(EXT) 24 | ./stabtest$(EXT) 25 | -------------------------------------------------------------------------------- /source/min-api/include/readerwriterqueue/tests/unittests/makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | ifeq ($(OS),Windows_NT) 4 | EXT=.exe 5 | PLATFORM_OPTS=-static 6 | PLATFORM_LD_OPTS=-Wl,--no-as-needed 7 | else 8 | UNAME_S := $(shell uname -s) 9 | ifeq ($(UNAME_S),Darwin) 10 | EXT= 11 | PLATFORM_OPTS= 12 | PLATFORM_LD_OPTS= 13 | else 14 | EXT= 15 | PLATFORM_OPTS= 16 | PLATFORM_LD_OPTS=-lrt -Wl,--no-as-needed 17 | endif 18 | endif 19 | 20 | 21 | default: unittests$(EXT) 22 | 23 | unittests$(EXT): unittests.cpp ../../readerwriterqueue.h ../../atomicops.h ../common/simplethread.h ../common/simplethread.cpp minitest.h makefile 24 | g++ $(PLATFORM_OPTS) -std=c++11 -Wsign-conversion -Wpedantic -Wall -DNDEBUG -O3 -g unittests.cpp ../common/simplethread.cpp -o unittests$(EXT) -pthread $(PLATFORM_LD_OPTS) 25 | 26 | run: unittests$(EXT) 27 | ./unittests$(EXT) 28 | -------------------------------------------------------------------------------- /source/min-api/script/min-package.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Min-API Authors. All rights reserved. 2 | # Use of this source code is governed by the MIT License found in the License.md file. 3 | 4 | include(${CMAKE_CURRENT_LIST_DIR}/../max-sdk-base/script/max-package.cmake) 5 | -------------------------------------------------------------------------------- /source/min-api/script/min-posttarget.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Min-API Authors. All rights reserved. 2 | # Use of this source code is governed by the MIT License found in the License.md file. 3 | 4 | include(${C74_MAX_SDK_DIR}/script/max-posttarget.cmake) 5 | 6 | set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) 7 | set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) 8 | 9 | option(C74_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) 10 | 11 | if (APPLE) 12 | set(C74_XCODE_WARNING_CFLAGS "-Wall -Wmissing-field-initializers -Wno-unused-lambda-capture -Wno-unknown-warning-option") 13 | if (${C74_WARNINGS_AS_ERRORS}) 14 | set(C74_XCODE_WARNING_CFLAGS "${C74_XCODE_WARNING_CFLAGS} -Werror") 15 | endif () 16 | 17 | # enforce a strict warning policy 18 | set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS ${C74_XCODE_WARNING_CFLAGS}) 19 | endif () 20 | -------------------------------------------------------------------------------- /source/min-lib/Authors.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | Names should be added to this file with this pattern: 3 | 4 | For individuals: 5 | `Name ` 6 | 7 | For organizations: 8 | `Organization ` 9 | 10 | 11 | 12 | ``` 13 | Cycling '74 <*@cycling74.com> 14 | Nathan Wolek 15 | Trond Lossius 16 | ``` 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /source/min-lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Min-Lib Authors. All rights reserved. 2 | # Use of this source code is governed by the MIT License found in the License.md file. 3 | 4 | cmake_minimum_required(VERSION 3.10) 5 | project(MinLib) 6 | 7 | 8 | if (${CMAKE_GENERATOR} MATCHES "Xcode") 9 | if (${XCODE_VERSION} VERSION_LESS 10) 10 | message(STATUS "Xcode 10 is required. Please install from the Mac App Store.") 11 | return () 12 | endif () 13 | endif () 14 | 15 | 16 | #include(${CMAKE_CURRENT_SOURCE_DIR}/script/min-package.cmake) 17 | 18 | 19 | file(GLOB_RECURSE MIN_LIB_HEADERS 20 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) 22 | add_custom_target( LIB ALL 23 | SOURCES ${MIN_LIB_HEADERS} 24 | ) 25 | 26 | 27 | # Add unit tests for the Lib 28 | if ("${THIS_PACKAGE_NAME}" MATCHES ".*devkit") 29 | 30 | enable_testing() 31 | 32 | SUBDIRLIST(TESTDIRS ${CMAKE_CURRENT_SOURCE_DIR}/test) 33 | foreach(testdir ${TESTDIRS}) 34 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/${testdir}/CMakeLists.txt") 35 | message("Generating Unit Test: ${testdir}") 36 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/${testdir}) 37 | endif () 38 | endforeach() 39 | 40 | endif () 41 | -------------------------------------------------------------------------------- /source/min-lib/License.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2018, The Min-Lib Authors. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /source/min-lib/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Min-Lib 2 | 3 | This folder contains building blocks, helper classes, and unit generators that may be useful in the authoring of C++ code for audio, video, and data processing. It is distributed as a part of the [Min-DevKit Package](https://github.com/Cycling74/min-devkit). Please refer to that package for additional documentation and best practices. 4 | 5 | ## Overview of Contents 6 | 7 | * `include` : header files 8 | * `doc` : documentation 9 | * `test` : supporting code and resources for unit testing 10 | 11 | ## License 12 | 13 | Use of this Max-Lib distribution is governed by the MIT License as stated in the accompanying `License.md` file. 14 | 15 | -------------------------------------------------------------------------------- /source/min-lib/include/c74_lib.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @ingroup minlib 3 | /// @copyright Copyright 2018 The Min-Lib Authors. All rights reserved. 4 | /// @license Use of this source code is governed by the MIT License found in the License.md file. 5 | 6 | #pragma once 7 | 8 | 9 | #include "c74_lib_circular_storage.h" 10 | #include "c74_lib_interpolator.h" 11 | #include "c74_lib_math.h" 12 | #include "c74_lib_easing.h" 13 | #include "c74_lib_filters.h" 14 | 15 | #include "c74_lib_adsr.h" 16 | #include "c74_lib_allpass.h" 17 | #include "c74_lib_dcblocker.h" 18 | #include "c74_lib_delay.h" 19 | #include "c74_lib_generator.h" 20 | #include "c74_lib_limiter.h" 21 | #include "c74_lib_onepole.h" 22 | #include "c74_lib_saturation.h" 23 | #include "c74_lib_sync.h" 24 | #include "c74_lib_oscillator.h" 25 | -------------------------------------------------------------------------------- /source/min-lib/include/c74_lib_dcblocker.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @ingroup minlib 3 | /// @copyright Copyright 2018 The Min-Lib Authors. All rights reserved. 4 | /// @license Use of this source code is governed by the MIT License found in the License.md file. 5 | 6 | #pragma once 7 | 8 | #include "c74_min_api.h" 9 | 10 | namespace c74::min::lib { 11 | 12 | 13 | /// one-channel dc-blocking filter 14 | 15 | class dcblocker { 16 | public: 17 | /// Clear the filter's history 18 | 19 | void clear() { 20 | x_1 = y_1 = 0.0; 21 | } 22 | 23 | 24 | /// Calculate one sample. 25 | /// @return Calculated sample 26 | 27 | sample operator()(sample x) { 28 | auto y = x - x_1 + y_1 * 0.9997; 29 | y_1 = y; 30 | x_1 = x; 31 | return y; 32 | } 33 | 34 | private: 35 | sample x_1{}; ///< feedforward history 36 | sample y_1{}; ///< feedback history 37 | }; 38 | 39 | 40 | } // namespace c74::min::lib 41 | -------------------------------------------------------------------------------- /source/projects/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${PRODUCT_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | ${PRODUCT_VERSION} 15 | CFBundleLongVersionString 16 | ${PRODUCT_NAME} ${PRODUCT_VERSION}, Copyright ${YEAR} ${DEVELOPER} 17 | CFBundlePackageType 18 | iLaX 19 | CFBundleShortVersionString 20 | ${PRODUCT_VERSION} 21 | CFBundleSignature 22 | max2 23 | CFBundleVersion 24 | ${PRODUCT_VERSION} 25 | CSResourcesFileMapped 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /source/projects/cobra/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `cobra` object 2 | 3 | ## [0.1.x] 4 | 5 | - Changed name of the project to `cobra` 6 | 7 | - Added new general build system 8 | 9 | ## [0.1.1] 10 | 11 | - Added changelog 12 | - Added py_interpreter.h 13 | -------------------------------------------------------------------------------- /source/projects/cobra/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | ) 8 | 9 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 10 | -------------------------------------------------------------------------------- /source/projects/jmx/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """Hello World server in Python 3 | 4 | - Binds REP socket to tcp://*:5555 5 | 6 | - Expects b"Hello" from client, replies with b"World" 7 | 8 | """ 9 | 10 | import time 11 | import zmq 12 | 13 | context = zmq.Context() 14 | socket = context.socket(zmq.REP) 15 | socket.bind("tcp://*:5555") 16 | 17 | while True: 18 | # Wait for next request from client 19 | message = socket.recv() 20 | print(f"Received request: {message}") 21 | 22 | # Do some 'work' 23 | time.sleep(1) 24 | 25 | # Send reply back to client 26 | socket.send_string("WORLD!!!") 27 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/Makefile: -------------------------------------------------------------------------------- 1 | CC = clang 2 | EXECUTABLES = $(patsubst %.c, %, $(wildcard *.c)) 3 | PYTHON_VERSION = $(shell python3 --version | sed s/Python[[:space:]]//) # 3.9.5 4 | PY_MAJOR = $(shell echo $(PYTHON_VERSION) | cut -f1 -d'.') 5 | PY_MINOR = $(shell echo $(PYTHON_VERSION) | cut -f2 -d'.') 6 | BREW_PREFIX = $(shell brew --prefix) 7 | PYTHON_VER = $(PY_MAJOR).$(PY_MINOR) # 3.9 8 | CFLAGS = $(shell python3-config --cflags) -I$(BREW_PREFIX)/include -L$(BREW_PREFIX)/lib 9 | LDFLAGS = $(shell python3-config --ldflags) -lpython$(PYTHON_VER) -lczmq -lzmq 10 | 11 | .PHONY: clean analyze 12 | 13 | all: $(EXECUTABLES) 14 | @echo compile zeromq python tests.. 15 | 16 | %: %.c 17 | @$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) 18 | 19 | analyze: 20 | @infer run -- make 21 | 22 | clean: 23 | @rm -f $(EXECUTABLES) 24 | @rm -rf *.dSYM 25 | @rm -rf infer-out 26 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | import zmq 5 | 6 | PORT="5555" 7 | 8 | def main(): 9 | print("Connecting to python server") 10 | context = zmq.Context() 11 | requester = context.socket(zmq.REQ) 12 | requester.connect("tcp://localhost:5555") 13 | 14 | for i in range(10): 15 | print(f"Sending 1+{i}") 16 | requester.send_string(f"1+{i}") 17 | response = requester.recv_string() 18 | print(f"Received: {response}") 19 | 20 | requester.close() 21 | context.destroy() 22 | 23 | main() 24 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/jupyter_client/test_kernelclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | from: https://stackoverflow.com/questions/33731744/executing-code-in-ipython-kernel-with-the-kernelclient-api 3 | 4 | get connection file from from 5 | 6 | jupyter --runtime-dir 7 | 8 | """ 9 | import os 10 | 11 | from jupyter_client.blocking import BlockingKernelClient 12 | 13 | RUNTIME_DIR = os.path.join(os.environ['HOME'], 'Library/Jupyter/runtime') 14 | CONNECTION_FILE = os.path.join(RUNTIME_DIR, 'kernel-29857.json') 15 | 16 | kc = BlockingKernelClient(connection_file=CONNECTION_FILE) 17 | kc.load_connection_file() 18 | kc.start_channels() 19 | msgid = kc.execute('a = 10') 20 | reply = kc.get_shell_msg(timeout=5) 21 | print(reply) 22 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/jupyter_client/test_kernelclient2.py: -------------------------------------------------------------------------------- 1 | """ 2 | from: https://stackoverflow.com/questions/33731744/executing-code-in-ipython-kernel-with-the-kernelclient-api 3 | 4 | get connection file from 5 | 6 | jupyter --runtime-dir 7 | 8 | """ 9 | import os 10 | from pprint import pprint 11 | 12 | from jupyter_client.consoleapp import JupyterConsoleApp 13 | 14 | RUNTIME_DIR = os.path.join(os.environ['HOME'], 'Library/Jupyter/runtime') 15 | CONNECTION_FILE = 'kernel-29857.json' 16 | 17 | 18 | class MyKernelApp(JupyterConsoleApp): 19 | def __init__(self, connection_file, runtime_dir): 20 | self._dispatching = False 21 | self.existing = connection_file 22 | self.runtime_dir = runtime_dir 23 | self.initialize() 24 | 25 | app = MyKernelApp(CONNECTION_FILE, RUNTIME_DIR) 26 | kc = app.kernel_client 27 | kc.execute("print 'hello'") 28 | msg = kc.iopub_channel.get_msg(block=True, timeout=1) 29 | pprint(msg) 30 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/pyclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | wchar_t *program = Py_DecodeLocale(argv[0], NULL); 8 | if (program == NULL) { 9 | fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); 10 | exit(1); 11 | } 12 | Py_SetProgramName(program); 13 | Py_Initialize(); 14 | 15 | PyRun_InteractiveLoop(stdin, ""); 16 | 17 | Py_Finalize(); 18 | PyMem_RawFree(program); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_czmq_client.c: -------------------------------------------------------------------------------- 1 | // Hello World client 2 | #include 3 | 4 | int main (void) 5 | { 6 | printf ("Connecting to hello world server…\n"); 7 | zsock_t *requester = zsock_new (ZMQ_REQ); 8 | zsock_connect (requester, "tcp://localhost:5555"); 9 | 10 | int request_nbr; 11 | for (request_nbr = 0; request_nbr != 10; request_nbr++) { 12 | printf ("Sending Hello %d…\n", request_nbr); 13 | zstr_send (requester, "Hello"); 14 | char *str = zstr_recv (requester); 15 | printf ("Received World %d\n", request_nbr); 16 | zstr_free (&str); 17 | } 18 | zsock_destroy (&requester); 19 | return 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_czmq_server.c: -------------------------------------------------------------------------------- 1 | // Hello World server 2 | #include 3 | 4 | int main (void) 5 | { 6 | // Socket to talk to clients 7 | zsock_t *responder = zsock_new(ZMQ_REP); 8 | int rc = zsock_bind(responder, "tcp://*:5555"); 9 | assert (rc == 0); 10 | 11 | while (1) { 12 | char *str = zstr_recv(responder); 13 | printf("Received '%s'\n", str); 14 | sleep(1); // Do some 'work' 15 | zstr_send(responder, "World"); 16 | zstr_free(&str); 17 | } 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_pczmq_client.c: -------------------------------------------------------------------------------- 1 | // Hello World client 2 | #include 3 | 4 | int main(void) 5 | { 6 | printf("Connecting to python server…\n"); 7 | zsock_t *requester = zsock_new(ZMQ_REQ); 8 | zsock_connect (requester, "tcp://localhost:5555"); 9 | 10 | char result[100]; 11 | for (int i = 0; i != 10; i++) { 12 | printf("Sending 1+%d\n", i); 13 | sprintf(result, "1+%d", i); 14 | zstr_send(requester, result); 15 | char *str = zstr_recv(requester); 16 | printf ("Received: %s\n", str); 17 | zstr_free (&str); 18 | } 19 | zsock_destroy (&requester); 20 | return 0; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_pzmq_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main (void) 7 | { 8 | printf("Connecting to python server\n"); 9 | void *context = zmq_ctx_new (); 10 | void *requester = zmq_socket (context, ZMQ_REQ); 11 | zmq_connect(requester, "tcp://localhost:5555"); 12 | 13 | char request[10]; 14 | for (int i = 0; i != 10; i++) { 15 | char response[10]; 16 | printf("Sending 1+%d\n", i); 17 | sprintf(request, "1+%d", i); 18 | zmq_send(requester, request, sizeof(request), 0); 19 | zmq_recv(requester, response, sizeof(response), 0); 20 | printf("Received %s\n", response); 21 | } 22 | zmq_close(requester); 23 | zmq_ctx_destroy(context); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_spawn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | extern char **environ; 10 | 11 | void run_cmd(char *cmd) 12 | { 13 | pid_t pid; 14 | char *argv[] = {"sh", "-c", cmd, NULL}; 15 | int status; 16 | printf("Run command: %s\n", cmd); 17 | status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); 18 | if (status == 0) { 19 | printf("Child pid: %i\n", pid); 20 | do { 21 | if (waitpid(pid, &status, 0) != -1) { 22 | printf("Child status %d\n", WEXITSTATUS(status)); 23 | } else { 24 | perror("waitpid"); 25 | exit(1); 26 | } 27 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 28 | } else { 29 | printf("posix_spawn: %s\n", strerror(status)); 30 | } 31 | } 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | run_cmd(argv[1]); 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_zmq_client.c: -------------------------------------------------------------------------------- 1 | // Hello World client 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main (void) 8 | { 9 | printf ("Connecting to hello world server…\n"); 10 | void *context = zmq_ctx_new (); 11 | void *requester = zmq_socket (context, ZMQ_REQ); 12 | zmq_connect (requester, "tcp://localhost:5555"); 13 | 14 | int request_nbr; 15 | for (request_nbr = 0; request_nbr != 10; request_nbr++) { 16 | char buffer [10]; 17 | printf ("Sending Hello %d…\n", request_nbr); 18 | zmq_send (requester, "Hello", 5, 0); 19 | zmq_recv (requester, buffer, 10, 0); 20 | printf ("Received World %d\n", request_nbr); 21 | } 22 | zmq_close (requester); 23 | zmq_ctx_destroy (context); 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /source/projects/jmx/tests/test_zmq_server.c: -------------------------------------------------------------------------------- 1 | // Hello World server 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main (void) 9 | { 10 | // Socket to talk to clients 11 | void *context = zmq_ctx_new(); 12 | void *responder = zmq_socket(context, ZMQ_REP); 13 | int rc = zmq_bind(responder, "tcp://*:5555"); 14 | assert (rc == 0); 15 | 16 | while (1) { 17 | char buffer [10]; 18 | zmq_recv (responder, buffer, 10, 0); 19 | printf ("Received Hello\n"); 20 | sleep (1); // Do some 'work' 21 | zmq_send (responder, "World", 5, 0); 22 | } 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /source/projects/krait/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `krait` object 2 | 3 | ## [0.1.x] 4 | 5 | - Changed name of the project to `krait` 6 | 7 | - Updated initialization code related to recently updated `mamba py.h` dependency 8 | 9 | - Added docs 10 | 11 | - Refactored to re-use mamba's `py.h` single-header library. 12 | -------------------------------------------------------------------------------- /source/projects/krait/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../mamba 8 | ) 9 | 10 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 11 | -------------------------------------------------------------------------------- /source/projects/krait/README.md: -------------------------------------------------------------------------------- 1 | # krait: an ITM-based python evaluator 2 | 3 | This project provide a proof-of-concept to defer the evaluation of a python function via Max's ITM-based sequencing. 4 | 5 | Note that it has a dependency on another subproject: it includes mamba's single header c library, `py.h`, to reduce boilerplate and provide python interpreter 'services'. 6 | 7 | ## Current Status 8 | 9 | Crashes on Python3.13 (this is under investigation) 10 | 11 | ## Building 12 | 13 | From the root of the `py-js` project 14 | 15 | ```bash 16 | make projects 17 | ``` 18 | 19 | This will build all subprojects, including `krait`, using the standard cmake buildsystem. 20 | 21 | ## Help 22 | 23 | See `krait.maxhelp` in `py-js/help` folder. 24 | -------------------------------------------------------------------------------- /source/projects/mamba/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `mamba` object 2 | 3 | ## [0.1.x] 4 | 5 | ## [0.1.2] 6 | 7 | - Merged `mambo` build system. 8 | 9 | - Changed build process to use re-usable cmake function. 10 | 11 | - Added `mamba-framework-pkg` build for Max packages. 12 | 13 | - Shared, static, and framework builds successful on macOS. 14 | 15 | - Added shared, static, and framework builds via: `make mamba-shared`, `make mamba-static` and `make mamba-framework` respectively. 16 | 17 | - Added a slightly modified version of the `source/scripts/buildpy.py` script which was [developed externally](https://github.com/shakfu/buildpy). 18 | 19 | - `mambo` project, based on `mamba`, created. 20 | 21 | ## [0.1.1] 22 | 23 | - Added `py_exec_file_input` and `py_exec_single_input` to support interactive console. -------------------------------------------------------------------------------- /source/projects/mamba/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | ) 8 | 9 | 10 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 11 | 12 | -------------------------------------------------------------------------------- /source/projects/mpy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | set(BUILD_SHARED_LIBS OFF) 5 | 6 | include(${CMAKE_CURRENT_SOURCE_DIR}/micropython.cmake) 7 | 8 | include_directories( 9 | "${MAX_SDK_INCLUDES}" 10 | "${MAX_SDK_MSP_INCLUDES}" 11 | "${MAX_SDK_JIT_INCLUDES}" 12 | ) 13 | 14 | file(GLOB PROJECT_SRC 15 | "*.h" 16 | "*.c" 17 | "*.cpp" 18 | ) 19 | 20 | add_library( 21 | ${PROJECT_NAME} 22 | MODULE 23 | ${PROJECT_SRC} 24 | # below is required for static library case due to extern definition 25 | $<$>:${EMBED_DIR}/py/mpstate.c> 26 | ) 27 | 28 | target_link_directories( 29 | ${PROJECT_NAME} 30 | PRIVATE 31 | ${CMAKE_CURRENT_SOURCE_DIR} 32 | ) 33 | 34 | target_link_libraries( 35 | ${PROJECT_NAME} 36 | PRIVATE 37 | ${MPY_LIB} 38 | ) 39 | 40 | 41 | target_include_directories(${PROJECT_NAME} 42 | PRIVATE 43 | ${MPY_INCLUDE_DIRECTORIES} 44 | ) 45 | 46 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 47 | -------------------------------------------------------------------------------- /source/projects/mpy/README.md: -------------------------------------------------------------------------------- 1 | # mpy: micropython external 2 | 3 | A proof-of-concept which embeds micropython in a max external 4 | 5 | Currently only tested on macOS. 6 | 7 | Can be built using `-DBUILD_MICROPYTHON_EXTERNAL` which will default to local micropython code. If the option `-DFETCH_MICROPYTHON` is used cmake will try to build from git clone. 8 | 9 | Doesn't do anything now useful except prove that embedding micropytho in an external is possible.. Still a work-in-progress and will be developed further as one familiarizes oneself with the micropython c-api. 10 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/genhdr/moduledefs.h: -------------------------------------------------------------------------------- 1 | // Automatically generated by makemoduledefs.py. 2 | 3 | extern const struct _mp_obj_module_t mp_module___main__; 4 | #undef MODULE_DEF___MAIN__ 5 | #define MODULE_DEF___MAIN__ { MP_ROM_QSTR(MP_QSTR___main__), MP_ROM_PTR(&mp_module___main__) }, 6 | 7 | extern const struct _mp_obj_module_t mp_module_builtins; 8 | #undef MODULE_DEF_BUILTINS 9 | #define MODULE_DEF_BUILTINS { MP_ROM_QSTR(MP_QSTR_builtins), MP_ROM_PTR(&mp_module_builtins) }, 10 | 11 | extern const struct _mp_obj_module_t mp_module_gc; 12 | #undef MODULE_DEF_GC 13 | #define MODULE_DEF_GC { MP_ROM_QSTR(MP_QSTR_gc), MP_ROM_PTR(&mp_module_gc) }, 14 | 15 | 16 | #define MICROPY_REGISTERED_MODULES \ 17 | MODULE_DEF_BUILTINS \ 18 | MODULE_DEF_GC \ 19 | MODULE_DEF___MAIN__ \ 20 | // MICROPY_REGISTERED_MODULES 21 | 22 | #define MICROPY_REGISTERED_EXTENSIBLE_MODULES \ 23 | // MICROPY_REGISTERED_EXTENSIBLE_MODULES 24 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/genhdr/mpversion.h: -------------------------------------------------------------------------------- 1 | // This file was generated by py/makeversionhdr.py 2 | #define MICROPY_GIT_TAG "v1.23.0" 3 | #define MICROPY_GIT_HASH "" 4 | #define MICROPY_BUILD_DATE "2024-06-04" 5 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/genhdr/root_pointers.h: -------------------------------------------------------------------------------- 1 | // Automatically generated by make_root_pointers.py. 2 | 3 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/port/mphalport.h: -------------------------------------------------------------------------------- 1 | // Define so there's no dependency on extmod/virtpin.h 2 | #define mp_hal_pin_obj_t 3 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/py/emitnarm.c: -------------------------------------------------------------------------------- 1 | // ARM specific stuff 2 | 3 | #include "py/mpconfig.h" 4 | 5 | #if MICROPY_EMIT_ARM 6 | 7 | // This is defined so that the assembler exports generic assembler API macros 8 | #define GENERIC_ASM_API (1) 9 | #include "py/asmarm.h" 10 | 11 | // Word indices of REG_LOCAL_x in nlr_buf_t 12 | #define NLR_BUF_IDX_LOCAL_1 (3) // r4 13 | 14 | #define N_ARM (1) 15 | #define EXPORT_FUN(name) emit_native_arm_##name 16 | #include "py/emitnative.c" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/py/emitnthumb.c: -------------------------------------------------------------------------------- 1 | // thumb specific stuff 2 | 3 | #include "py/mpconfig.h" 4 | 5 | #if MICROPY_EMIT_THUMB 6 | 7 | // this is defined so that the assembler exports generic assembler API macros 8 | #define GENERIC_ASM_API (1) 9 | #include "py/asmthumb.h" 10 | 11 | // Word indices of REG_LOCAL_x in nlr_buf_t 12 | #define NLR_BUF_IDX_LOCAL_1 (3) // r4 13 | 14 | #define N_THUMB (1) 15 | #define EXPORT_FUN(name) emit_native_thumb_##name 16 | #include "py/emitnative.c" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/py/emitnx64.c: -------------------------------------------------------------------------------- 1 | // x64 specific stuff 2 | 3 | #include "py/mpconfig.h" 4 | 5 | #if MICROPY_EMIT_X64 6 | 7 | // This is defined so that the assembler exports generic assembler API macros 8 | #define GENERIC_ASM_API (1) 9 | #include "py/asmx64.h" 10 | 11 | // Word indices of REG_LOCAL_x in nlr_buf_t 12 | #define NLR_BUF_IDX_LOCAL_1 (5) // rbx 13 | 14 | #define N_X64 (1) 15 | #define EXPORT_FUN(name) emit_native_x64_##name 16 | #include "py/emitnative.c" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/py/emitnxtensa.c: -------------------------------------------------------------------------------- 1 | // Xtensa specific stuff 2 | 3 | #include "py/mpconfig.h" 4 | 5 | #if MICROPY_EMIT_XTENSA 6 | 7 | // this is defined so that the assembler exports generic assembler API macros 8 | #define GENERIC_ASM_API (1) 9 | #include "py/asmxtensa.h" 10 | 11 | // Word indices of REG_LOCAL_x in nlr_buf_t 12 | #define NLR_BUF_IDX_LOCAL_1 (8) // a12 13 | 14 | #define N_XTENSA (1) 15 | #define EXPORT_FUN(name) emit_native_xtensa_##name 16 | #include "py/emitnative.c" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /source/projects/mpy/micropython_embed/py/emitnxtensawin.c: -------------------------------------------------------------------------------- 1 | // Xtensa-Windowed specific stuff 2 | 3 | #include "py/mpconfig.h" 4 | 5 | #if MICROPY_EMIT_XTENSAWIN 6 | 7 | // this is defined so that the assembler exports generic assembler API macros 8 | #define GENERIC_ASM_API (1) 9 | #define GENERIC_ASM_API_WIN (1) 10 | #include "py/asmxtensa.h" 11 | 12 | // Word indices of REG_LOCAL_x in nlr_buf_t 13 | #define NLR_BUF_IDX_LOCAL_1 (2 + 4) // a4 14 | 15 | #define N_NLR_SETJMP (1) 16 | #define N_XTENSAWIN (1) 17 | #define EXPORT_FUN(name) emit_native_xtensawin_##name 18 | #include "py/emitnative.c" 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /source/projects/mpy/mpconfigport.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the MicroPython project, http://micropython.org/ 2 | * The MIT License (MIT) 3 | * Copyright (c) 2022-2023 Damien P. George 4 | */ 5 | 6 | // Include common MicroPython embed configuration. 7 | #include 8 | 9 | // Use the minimal starting configuration (disables all optional features). 10 | #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM) 11 | 12 | // MicroPython configuration. 13 | #define MICROPY_ENABLE_COMPILER (1) 14 | #define MICROPY_ENABLE_GC (1) 15 | #define MICROPY_PY_GC (1) 16 | -------------------------------------------------------------------------------- /source/projects/mpyx/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `mpyx` object 2 | 3 | ## TODO 4 | 5 | - Add `empty()` method to `c74::min::atom` 6 | 7 | ## [0.0.1] 8 | 9 | - Implemented core Python interpreter functionality: 10 | - Python code execution and evaluation 11 | - Module importing 12 | - Error handling and logging 13 | - Data type conversion between Python and Max/MSP 14 | - File and path management 15 | - Table operations 16 | - Added thread-safe Python execution with GIL management 17 | - Added automatic memory management for Python objects 18 | - Added cross-platform support (macOS/Windows) 19 | - Added path management for resources 20 | - Added support for both static and shared builds 21 | - Added `mpy_interpreter.h` single-header library for Python 3 integration 22 | -------------------------------------------------------------------------------- /source/projects/mpyx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.0) 3 | 4 | set(C74_MIN_API_DIR ${CMAKE_SOURCE_DIR}/source/min-api) 5 | include(${C74_MIN_API_DIR}/script/min-pretarget.cmake) 6 | # include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/common.cmake) 7 | 8 | python3_external( 9 | MIN_API 10 | PROJECT_NAME ${PROJECT_NAME} 11 | BUILD_VARIANT ${BUILD_VARIANT} 12 | ) 13 | 14 | 15 | include(${C74_MIN_API_DIR}/script/min-posttarget.cmake) 16 | -------------------------------------------------------------------------------- /source/projects/mpyx/README.md: -------------------------------------------------------------------------------- 1 | # mpyx: a single-header c++ python3 library for min-api max externals 2 | 3 | This is a proof-of-concept external using a variant of the `py_interpreter.h` single-header c++ python3 library from the `cobra` project, called `mpy_interpreter.h`, which is compatible for use with [min-api](https://github.com/cycling74/min-api)-based projects. 4 | 5 | ## Usage 6 | 7 | This can be built individually with: 8 | 9 | ```sh 10 | make mpyx 11 | ``` 12 | 13 | For a relocatable dynamically-linked build 14 | 15 | ```sh 16 | make mpyx-shared 17 | ``` 18 | 19 | For a relocatable statically-linked build 20 | 21 | ```sh 22 | make mpyx-static 23 | ``` 24 | -------------------------------------------------------------------------------- /source/projects/mxpy/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `mxpy` object 2 | 3 | 4 | ## [0.0.1] 5 | 6 | -------------------------------------------------------------------------------- /source/projects/mxpy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | ) 8 | 9 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 10 | -------------------------------------------------------------------------------- /source/projects/pktpy/.gitignore: -------------------------------------------------------------------------------- 1 | demo 2 | *.gch 3 | test_dylib 4 | test_gch 5 | 6 | -------------------------------------------------------------------------------- /source/projects/pktpy/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | 4 | ## [0.0.2] 5 | 6 | - Update `pocketpy` to `v1.4.6` 7 | 8 | - Updated `pocketpy` to `v1.4.0` with simplified binding-logic 9 | 10 | - Updated to 1.3.2 with fix for breaking change re: changed `_stdout` and `_stderr` signatures. 11 | 12 | - Updated to [pocketpy](https://github.com/blueloveTH/pocketpy) to ver 1.2.0 13 | 14 | - Changed `PktpyInterpreter` to be a subclass of `pkpy::VM` 15 | 16 | 17 | 18 | ## [0.0.1] 19 | 20 | - Added code-editor support 21 | 22 | - Added `execfile` method. 23 | 24 | - Added list support. 25 | 26 | - Added examples of wrapping max api and local functions. 27 | 28 | - Added `anything` method. 29 | 30 | - Added the `pktpy` project which demonstrates use of [pocketpy](https://github.com/blueloveTH/pocketpy) as a max external. 31 | -------------------------------------------------------------------------------- /source/projects/pktpy/TODO.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | 3 | - [ ] add `dsp` module 4 | 5 | - [x] add smarter removal of Max escape sequences. (added method not yet enabled) 6 | 7 | - [ ] add additional support for container types (list, tuple, set, slice, range) 8 | 9 | - [ ] wrap more of max api 10 | 11 | -------------------------------------------------------------------------------- /source/projects/pktpy/scripts/demo.py: -------------------------------------------------------------------------------- 1 | a = 10 2 | b = "s" 3 | c = 2.1 4 | d = [1,2,3,4] 5 | 6 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/inherit/build.sh: -------------------------------------------------------------------------------- 1 | g++ --std=c++17 \ 2 | -O2 \ 3 | -Wall \ 4 | -Wfatal-errors \ 5 | -Wno-sign-compare \ 6 | -Wno-unused-variable \ 7 | -fno-rtti \ 8 | -stdlib=libc++ \ 9 | -I../.. \ 10 | -o main \ 11 | main.cpp 12 | 13 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/inherit/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pocketpy.h" 2 | #include "stdio.h" 3 | 4 | using namespace pkpy; 5 | 6 | class PktpyInterpreter : public VM { }; 7 | 8 | int main() { 9 | PktpyInterpreter *py = new PktpyInterpreter(); 10 | PyObject* result = py->exec("1+1", "", EVAL_MODE); 11 | if (is_int(result)) { 12 | int int_result = py_cast(py, result); 13 | printf("result: %d\n", int_result); 14 | } 15 | } -------------------------------------------------------------------------------- /source/projects/pktpy/tests/pocketpy_dylib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(CMAKE_BUILD_TYPE "Release") 3 | 4 | add_library( 5 | dsp 6 | SHARED 7 | dsp.c 8 | pocketpy_c.c 9 | ) 10 | 11 | target_include_directories( 12 | dsp 13 | PRIVATE 14 | ${CMAKE_CURRENT_SOURCE_DIR} 15 | ) 16 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/pocketpy_dylib/README.md: -------------------------------------------------------------------------------- 1 | # Experiments with PocketPy's Dynamic Loading 2 | 3 | - make this folder a cmake subfolder via `add_subfolder` right below `pktpy` to 4 | test. 5 | 6 | 7 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/pocketpy_dylib/dsp.c: -------------------------------------------------------------------------------- 1 | #include "pocketpy_c.h" 2 | #include 3 | #include 4 | 5 | static int hello(pkpy_vm* vm){ 6 | printf("Hello from dylib!\n"); 7 | return 0; 8 | } 9 | 10 | PK_EXPORT 11 | const char* pkpy_module__init__(pkpy_vm* vm, const char* version){ 12 | printf("version: %s\n", version); 13 | pkpy_push_function(vm, "hello()", hello); 14 | pkpy_push_module(vm, "dsp"); 15 | pkpy_setattr(vm, pkpy_name("hello")); 16 | // check if initialization failed 17 | if(pkpy_clear_error(vm, NULL)) return NULL; 18 | return "dsp"; 19 | } 20 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_c/build.sh: -------------------------------------------------------------------------------- 1 | TARGET="demo" 2 | 3 | echo "compiling ${TARGET}" 4 | time clang++ --std=c++17 -I../.. -o "${TARGET}" "${TARGET}.cpp" 5 | 6 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_c/demo.cpp: -------------------------------------------------------------------------------- 1 | #include "pocketpy.h" 2 | 3 | int main(){ 4 | // Create a virtual machine 5 | pkpy::VM* vm = pkpy_new_vm(true); 6 | 7 | // Hello world! 8 | pkpy_vm_exec(vm, "print('Hello world!')"); 9 | 10 | // Create a list 11 | pkpy_vm_exec(vm, "a = [1, 2, 3]"); 12 | 13 | // Eval the sum of the list 14 | char* result = pkpy_vm_eval(vm, "sum(a)"); 15 | printf("%s", result); // 6 16 | 17 | // Free the resources 18 | pkpy_delete(result); 19 | pkpy_delete(vm); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_cpp/build.sh: -------------------------------------------------------------------------------- 1 | TARGET="demo" 2 | 3 | echo "compiling ${TARGET}" 4 | time clang++ --std=c++17 -I../.. -o "${TARGET}" "${TARGET}.cpp" 5 | 6 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_cpp/test.py: -------------------------------------------------------------------------------- 1 | def test(): 2 | return 'hello world' 3 | 4 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_cpp2/build.sh: -------------------------------------------------------------------------------- 1 | TARGET="demo" 2 | 3 | echo "compiling ${TARGET} with exception support" 4 | time clang++ --std=c++17 -fexceptions -I../.. -o "${TARGET}" "${TARGET}.cpp" 5 | 6 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_cpp2/demo.cpp: -------------------------------------------------------------------------------- 1 | #include "pocketpy.h" 2 | 3 | using namespace pkpy; 4 | 5 | int main(){ 6 | // Create a virtual machine 7 | VM* vm = new VM(true); 8 | 9 | // Hello world! 10 | vm->exec("print('Hello world!')", "main.py", EXEC_MODE); 11 | 12 | // Create a list 13 | vm->exec("a = [1, 2, 3]", "main.py", EXEC_MODE); 14 | 15 | // Eval the sum of the list 16 | PyVar result = vm->exec("sum(a)", "", EVAL_MODE); 17 | 18 | // std::cout << py_cast(vm, result); // 6 19 | std::cout << py_cast(vm, result); 20 | 21 | PyVar s = VAR("abc"); 22 | Str st = CAST(Str, s); // Str is a subclass of std::string 23 | 24 | printf("\nas c string: %s\n", st.c_str()); 25 | 26 | std::cout << st; 27 | 28 | // std::cout << CAST(Str, s); // abc 29 | 30 | // exception 31 | // std::cout << CAST(Str, result); 32 | 33 | // not working 34 | // char *str = CAST(Str, result); 35 | // std::cout << str; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_str_replace/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/pktpy/tests/test_str_replace/main -------------------------------------------------------------------------------- /source/projects/pktpy/tests/test_str_replace/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // build: g++ -o main main.cpp 5 | 6 | bool replace(std::string& str, const std::string& from, const std::string& to) { 7 | size_t start_pos = str.find(from); 8 | if(start_pos == std::string::npos) 9 | return false; 10 | str.replace(start_pos, from.length(), to); 11 | return true; 12 | } 13 | 14 | int main() 15 | { 16 | std::cout << "testing basic replace" << std::endl; 17 | std::string string1("hello $name"); 18 | replace(string1, "$name", "Somename"); 19 | assert(string1.compare("hello Somename") == 0); 20 | std::cout << "hello $name -> " << string1 << std::endl; 21 | 22 | std::cout << std::endl; 23 | 24 | std::cout << "testing replace with empty string" << std::endl; 25 | std::string string2("hello \\$name"); 26 | replace(string2, "\\", ""); 27 | assert(string2.compare("hello $name") == 0); 28 | std::cout << "hello \\$name -> " << string2 << std::endl; 29 | } -------------------------------------------------------------------------------- /source/projects/pktpy2/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | 4 | 5 | 6 | ## [0.0.1] 7 | 8 | - Added `pktpy2_import` 9 | 10 | - Added basic methods 11 | 12 | - Added `pktpy2.maxhelp` 13 | 14 | - Created new external from backwards incompatible pocketpy version 2.0.5 -------------------------------------------------------------------------------- /source/projects/pktpy2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | cmake_minimum_required(VERSION 3.10) 5 | 6 | 7 | set(CMAKE_C_STANDARD 11) 8 | set(CMAKE_C_STANDARD_REQUIRED ON) 9 | set(CMAKE_BUILD_TYPE "Release") 10 | 11 | 12 | file(GLOB PROJECT_SRC 13 | "*.h" 14 | "*.c" 15 | "*.cpp" 16 | ) 17 | 18 | include_directories( 19 | "${MAX_SDK_INCLUDES}" 20 | "${MAX_SDK_MSP_INCLUDES}" 21 | "${MAX_SDK_JIT_INCLUDES}" 22 | ) 23 | 24 | add_library( 25 | ${PROJECT_NAME} 26 | MODULE 27 | ${PROJECT_SRC} 28 | ) 29 | 30 | target_include_directories( 31 | ${PROJECT_NAME} 32 | PUBLIC 33 | ${CMAKE_CURRENT_SOURCE_DIR} 34 | ${THIRDPARTY_DEPS}/pocketpy 35 | ) 36 | 37 | target_link_libraries( 38 | ${PROJECT_NAME} 39 | PUBLIC 40 | pocketpy 41 | ) 42 | 43 | 44 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 45 | -------------------------------------------------------------------------------- /source/projects/pktpy2/README.md: -------------------------------------------------------------------------------- 1 | # pktpy2: a pocketpy v2.0.x max external 2 | 3 | This external embeds version `2.0.8` of [pocketpy](https://github.com/blueloveTH/pocketpy), a Python interpreter for game engines, in a Max external. It is called `pktpy2` to differentiate it from the `pktpy` external which is based on the version `1.4.6` of `pocketpy`. 4 | 5 | The major difference / benefit between v2 and v1 is that the lua-like c-api used in the v2 implementation makes the external a good deal smaller (572KB for v2 vs 1.3MB for v1 so far). 6 | 7 | -------------------------------------------------------------------------------- /source/projects/pktpy2/TODO.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | 3 | - [ ] initial external 4 | -------------------------------------------------------------------------------- /source/projects/pktpy2/tests/call/f_args.c: -------------------------------------------------------------------------------- 1 | #include "pocketpy.h" 2 | #include 3 | 4 | /* 5 | 6 | print_args(1, '2', 3.0, True, [None, ('a', 'b')]) 7 | 8 | a = [i for i in range(5)] 9 | print_args(*a) 10 | 11 | */ 12 | 13 | 14 | #define INPUT "" 15 | 16 | static bool print_args(int argc, py_Ref argv) { 17 | PY_CHECK_ARGC(1); // single arg: `*args` tuple 18 | PY_CHECK_ARG_TYPE(0, tp_tuple); // check that it is 19 | 20 | int tuple_len = py_tuple_len(py_arg(0)); 21 | 22 | printf("tuple_len: %d\n", tuple_len); 23 | for(int i = 0; i < tuple_len; i++) { 24 | py_Ref tuple_item = py_tuple_getitem(py_arg(0), i); 25 | if (!py_str(tuple_item)) { 26 | return false; 27 | } 28 | printf("%s\n", py_tostr(py_retval())); 29 | } 30 | py_newnone(py_retval()); 31 | return true; 32 | } 33 | 34 | int main() { 35 | py_initialize(); 36 | 37 | py_GlobalRef __main__ = py_getmodule("__main__"); 38 | py_bind(__main__, "print_args(*args)", print_args); 39 | 40 | if (!py_exec(INPUT, "main.py", EXEC_MODE, NULL)) { 41 | py_printexc(); 42 | } 43 | 44 | py_finalize(); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /source/projects/pktpy2/tests/call/f_kwds.c: -------------------------------------------------------------------------------- 1 | #include "pocketpy.h" 2 | #include 3 | 4 | /* 5 | 6 | print_kwds(a=1, b=2) 7 | 8 | 9 | */ 10 | 11 | 12 | #define INPUT "" 13 | 14 | 15 | static bool my_print_kw_dict_apply(py_Ref key, py_Ref value, void *ctx) { 16 | const char *sep = (const char *)ctx; 17 | if (!py_str(key)) return false; 18 | printf("%s", py_tostr(py_retval())); 19 | if (!py_str(value)) return false; 20 | printf("%s%s\n", sep, py_tostr(py_retval())); 21 | return true; 22 | } 23 | 24 | static bool print_kwds(int argc, py_Ref argv) { 25 | PY_CHECK_ARGC(2); 26 | PY_CHECK_ARG_TYPE(0, tp_str); 27 | PY_CHECK_ARG_TYPE(1, tp_dict); 28 | const char *sep = py_tostr(py_arg(0)); 29 | bool ok = py_dict_apply(py_arg(1), my_print_kw_dict_apply, (void *)sep); 30 | if (!ok) return false; 31 | py_newnone(py_retval()); 32 | return true; 33 | } 34 | 35 | int main() { 36 | py_initialize(); 37 | 38 | py_GlobalRef __main__ = py_getmodule("__main__"); 39 | py_bind(__main__, "print_kwds(**kwds)", print_kwds); 40 | 41 | if (!py_exec(INPUT, "main.py", EXEC_MODE, NULL)) { 42 | py_printexc(); 43 | } 44 | 45 | py_finalize(); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /source/projects/pktpy2/tests/print_args/print_args.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pocketpy.h" 3 | 4 | static bool print_args(int argc, py_Ref argv) { 5 | py_ObjectRef tuple_item; 6 | py_i64 long_item; 7 | py_TValue* args = py_tuple_data(argv); 8 | int tuple_len = py_tuple_len(argv); 9 | printf("tuple_len: %d", tuple_len); 10 | PY_CHECK_ARGC(1); // single arg: `*args` tuple 11 | PY_CHECK_ARG_TYPE(0, tp_tuple); // check that it is 12 | for(int i = 0; i < tuple_len; i++) { 13 | tuple_item = py_tuple_getitem(py_arg(0), i); 14 | long_item = py_toint(tuple_item); 15 | printf("%d: %d", i, (int)long_item); 16 | } 17 | py_newnone(py_retval()); 18 | return true; 19 | } 20 | 21 | bool demo_module_initialize(void) { 22 | py_GlobalRef mod = py_newmodule("demo"); 23 | py_bind(mod, "print_args(*args)", print_args); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /source/projects/pktpy2/tests/test_iter/Makefile: -------------------------------------------------------------------------------- 1 | PKTPY2 = ../.. 2 | 3 | C_DEFS = -DPK_ENABLE_OS=1 -Wno-shorten-64-to-32 4 | 5 | .PHONY: all build clean 6 | 7 | all: build 8 | 9 | build: 10 | @clang -std=c11 -o test_iter test_iter.c $(PKTPY2)/pocketpy.c -I$(PKTPY2) $(C_DEFS) 11 | 12 | clean: 13 | @rm -f ./test_iter 14 | -------------------------------------------------------------------------------- /source/projects/py/.gitignore: -------------------------------------------------------------------------------- 1 | # dirs to exclude 2 | build/ 3 | scratch/ 4 | infer-out 5 | .DS_Store 6 | 7 | # py related 8 | __pycache__ 9 | .pytest_cache 10 | deploy 11 | 12 | project.xcworkspace 13 | xcuserdata 14 | 15 | # Prerequisites 16 | *.d 17 | 18 | # Object files 19 | *.o 20 | *.ko 21 | *.obj 22 | *.elf 23 | 24 | # Linker output 25 | *.ilk 26 | *.map 27 | *.exp 28 | 29 | # Precompiled Headers 30 | *.gch 31 | *.pch 32 | 33 | # Libraries 34 | *.lib 35 | #*.a 36 | *.la 37 | *.lo 38 | 39 | # Shared objects (inc. Windows DLLs) 40 | *.dll 41 | *.so 42 | *.so.* 43 | *.dylib 44 | 45 | # Executables 46 | *.exe 47 | *.out 48 | *.app 49 | *.i*86 50 | *.x86_64 51 | *.hex 52 | 53 | # Debug files 54 | *.dSYM/ 55 | *.su 56 | *.idb 57 | *.pdb 58 | 59 | # Kernel Module Compile Results 60 | *.mod* 61 | *.cmd 62 | .tmp_versions/ 63 | modules.order 64 | Module.symvers 65 | Mkfile.old 66 | dkms.conf 67 | -------------------------------------------------------------------------------- /source/projects/py/builder/__init__.py: -------------------------------------------------------------------------------- 1 | # builder: a python and max python3 external builder. 2 | -------------------------------------------------------------------------------- /source/projects/py/builder/ext/__init__.py: -------------------------------------------------------------------------------- 1 | # For external libs (all rights reserved for original authors) 2 | -------------------------------------------------------------------------------- /source/projects/py/builder/ext/relocatable_python/requirements_python2_recommended.txt: -------------------------------------------------------------------------------- 1 | xattr==0.6.4 2 | pyobjc==5.3 -------------------------------------------------------------------------------- /source/projects/py/builder/ext/relocatable_python/requirements_python3_recommended.txt: -------------------------------------------------------------------------------- 1 | --no-binary :all: 2 | xattr 3 | cffi 4 | pyobjc 5 | six -------------------------------------------------------------------------------- /source/projects/py/notes/build-variants.md: -------------------------------------------------------------------------------- 1 | # Build Variants 2 | 3 | 4 | ## current 5 | framework-ext 6 | framework-pkg 7 | homebrew-ext 8 | homebrew-pkg 9 | relocatable-pkg 10 | shared-ext 11 | shared-pkg 12 | static-ext 13 | local-sys 14 | 15 | # experimental 16 | static-pkg 17 | vanilla-ext 18 | vanilla-pkg 19 | beeware-ext 20 | beeware-pkg 21 | 22 | 23 | ## xcodegen 24 | xg-demo 25 | xg-framework-ext 26 | xg-shared-3.7 27 | xg-shared-ext 28 | xg-static-3.7 29 | xg-static-ext -------------------------------------------------------------------------------- /source/projects/py/notes/limitedapi-py.md: -------------------------------------------------------------------------------- 1 | # Python Limited API Compliance for `py` 2 | 3 | ## Not Compliant 4 | 5 | ```c 6 | Py_InitializeFromConfig() 7 | PyByteArray_Check() 8 | PyBytes_Check() 9 | PyConfig_Clear() 10 | PyConfig_InitPythonConfig() 11 | PyLong_Check() 12 | PyMem_RawFree() // PY_37 13 | PyRun_String() 14 | PyStatus_Exception() 15 | PyUnicode_AsUTF8() // but PyUnicode_AsUTF8String() is available 16 | PyUnicode_Check() 17 | ``` 18 | 19 | ## Compliant 20 | 21 | ```c 22 | Py_CompileString() 23 | Py_Finalize() 24 | Py_Initialize() 25 | Py_IsNone() 26 | Py_SetPythonHome() 27 | PyDict_GetItemString() 28 | PyDict_SetItemString() 29 | PyErr_Fetch() 30 | PyErr_NormalizeException() 31 | PyErr_Occurred() 32 | PyEval_EvalCode() 33 | PyEval_GetBuiltins() 34 | PyFloat_AsDouble() 35 | PyFloat_Check() 36 | PyFloat_FromDouble() 37 | PyGILState_Ensure() 38 | PyGILState_Release() 39 | PyImport_AddModule() 40 | PyImport_AppendInittab() 41 | PyList_Append() 42 | PyList_New() 43 | PyList_Size() 44 | PyLong_AsLong() 45 | PyLong_FromLong() 46 | PyModule_GetDict() 47 | PyObject_CallFunctionObjArgs() 48 | PyObject_GetIter() 49 | PyObject_Repr() 50 | PySequence_Check() 51 | PySequence_Length() 52 | PySys_GetObject() 53 | PyUnicode_FromString() 54 | ``` 55 | -------------------------------------------------------------------------------- /source/projects/py/pyjs.c: -------------------------------------------------------------------------------- 1 | ../pyjs/pyjs.c -------------------------------------------------------------------------------- /source/projects/py/pyjs.h: -------------------------------------------------------------------------------- 1 | ../pyjs/pyjs.h -------------------------------------------------------------------------------- /source/projects/py/resources/cflow/ignore.txt: -------------------------------------------------------------------------------- 1 | py_init_osx_set_home_static_ext 2 | py_init_osx_set_home_shared_pkg 3 | CFURLCreateCopyAppendingPathComponent 4 | CFStringCreateWithCString 5 | CFURLCreateCopyDeletingLastPathComponent 6 | CFBundleCopyBundleURL 7 | Py_SetPythonHome 8 | CFRelease 9 | Py_DecodeLocale 10 | CFStringGetCStringPtr 11 | CFURLCopyFileSystemPath 12 | CFURLCopyAbsoluteURL 13 | CFBundleCopyResourcesDirectoryURL -------------------------------------------------------------------------------- /source/projects/py/resources/cflow/mamba_cflow0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/py/resources/cflow/mamba_cflow0.pdf -------------------------------------------------------------------------------- /source/projects/py/resources/cflow/py_cflow0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/py/resources/cflow/py_cflow0.pdf -------------------------------------------------------------------------------- /source/projects/py/resources/entitlements/entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.allow-unsigned-executable-memory 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.12/Setup.diff: -------------------------------------------------------------------------------- 1 | 166,170c166,169 2 | < #_md5 md5module.c 3 | < #_sha1 sha1module.c 4 | < #_sha256 sha256module.c 5 | < #_sha512 sha512module.c 6 | < #_sha3 _sha3/sha3module.c 7 | --- 8 | > #_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE 9 | > #_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE 10 | > #_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a 11 | > #_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE 12 | 278c277 13 | < xxsubtype xxsubtype.c # Required for the test suite to pass! 14 | --- 15 | > #xxsubtype xxsubtype.c 16 | 282a282 17 | > #_xxinterpchannels _xxinterpchannelsmodule.c 18 | 293a294 19 | > #_testsinglephase _testsinglephase.c 20 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.13/Setup.diff: -------------------------------------------------------------------------------- 1 | 139a140,142 2 | > #_interpchannels _interpchannelsmodule.c 3 | > #_interpqueues _interpqueuesmodule.c 4 | > #_interpreters _interpretersmodule.c 5 | 153d155 6 | < #audioop audioop.c 7 | 158a161 8 | > #_sysconfig _sysconfig.c 9 | 187d189 10 | < #ossaudiodev ossaudiodev.c 11 | 189d190 12 | < #spwd spwdmodule.c 13 | 193,197d193 14 | < # Modules with UNIX dependencies that require external libraries 15 | < 16 | < #_crypt _cryptmodule.c -lcrypt 17 | < #nis nismodule.c -I/usr/include/tirpc -lnsl -ltirpc 18 | < 19 | 265c261 20 | < # Some system have -lcurses 21 | --- 22 | > # Some system have -lcurses 23 | 281,282d276 24 | < #_xxsubinterpreters _xxsubinterpretersmodule.c 25 | < #_xxinterpchannels _xxinterpchannelsmodule.c 26 | 293a288 27 | > #_testexternalinspection _testexternalinspection.c 28 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.6/setup-shared.local: -------------------------------------------------------------------------------- 1 | # -*- makefile -*- 2 | *disabled* 3 | 4 | _ctypes 5 | #_sqlite3 6 | _tkinter 7 | _curses 8 | _curses_panel 9 | xxlimited 10 | xxsubtype 11 | _multibytecodec 12 | _codecs_jp 13 | _codecs_kr 14 | _codecs_tw 15 | _codecs_cn 16 | _codecs_hk 17 | _codecs_iso2022 18 | 19 | _lzma 20 | _gdbm 21 | audioop 22 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.7/setup-shared.local: -------------------------------------------------------------------------------- 1 | # -*- makefile -*- 2 | zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz 3 | 4 | *disabled* 5 | 6 | _ctypes 7 | _sqlite3 8 | _tkinter 9 | _curses 10 | _curses_panel 11 | pyexpat 12 | xxlimited 13 | xxsubtype 14 | _multibytecodec 15 | _codecs_jp 16 | _codecs_kr 17 | _codecs_tw 18 | _codecs_cn 19 | _codecs_hk 20 | _codecs_iso2022 21 | 22 | _lzma 23 | _gdbm 24 | audioop 25 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.8/setup-shared.local: -------------------------------------------------------------------------------- 1 | # -*- makefile -*- 2 | *disabled* 3 | 4 | _ctypes 5 | #_sqlite3 6 | _tkinter 7 | _curses 8 | _curses_panel 9 | xxlimited 10 | xxsubtype 11 | _multibytecodec 12 | _codecs_jp 13 | _codecs_kr 14 | _codecs_tw 15 | _codecs_cn 16 | _codecs_hk 17 | _codecs_iso2022 18 | 19 | _lzma 20 | _gdbm 21 | audioop 22 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/3.9/Setup.orig-diff-from-3.8.diff: -------------------------------------------------------------------------------- 1 | 135c135,138 2 | < _tracemalloc _tracemalloc.c hashtable.c 3 | --- 4 | > _tracemalloc _tracemalloc.c 5 | > 6 | > # PEG-based parser module -- slated to be *the* parser 7 | > _peg_parser _peg_parser.c 8 | 170,171c173,174 9 | < #cmath cmathmodule.c _math.c # -lm # complex math library functions 10 | < #math mathmodule.c _math.c # -lm # math library functions, e.g. sin() 11 | --- 12 | > #cmath cmathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # complex math library functions 13 | > #math mathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # math library functions, e.g. sin() 14 | 177c180 15 | < #_random _randommodule.c # Random number generator 16 | --- 17 | > #_random _randommodule.c -DPy_BUILD_CORE_MODULE # Random number generator 18 | 180a184 19 | > #_zoneinfo _zoneinfo.c # zoneinfo accelerator 20 | 250,251c254,255 21 | < #_sha256 sha256module.c 22 | < #_sha512 sha512module.c 23 | --- 24 | > #_sha256 sha256module.c -DPy_BUILD_CORE_BUILTIN 25 | > #_sha512 sha512module.c -DPy_BUILD_CORE_BUILTIN 26 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/README.md: -------------------------------------------------------------------------------- 1 | # Module Setup Patches 2 | 3 | This folder contains patches to `Python-x.x.x/Modules/makesetup` and versions of `Python-x.x.x/Modules/Setup.local`. 4 | 5 | ## Notes 6 | 7 | - The patch to `makesetup` doesn't make a big difference. It's not worth the complexity and could potentially be dropped. 8 | -------------------------------------------------------------------------------- /source/projects/py/resources/patch/python-cmake-buildsystem/scproxy.patch: -------------------------------------------------------------------------------- 1 | diff --git a/cmake/extensions/CMakeLists.txt b/cmake/extensions/CMakeLists.txt 2 | index cdc1520..d9be461 100644 3 | --- a/cmake/extensions/CMakeLists.txt 4 | +++ b/cmake/extensions/CMakeLists.txt 5 | @@ -203,7 +203,7 @@ set(_scproxy3_SOURCES ${SRC_DIR}/Modules/_scproxy.c) 6 | add_python_extension(_scproxy 7 | REQUIRES APPLE HAVE_LIBSYSTEMCONFIGURATION 8 | SOURCES ${_scproxy${PY_VERSION_MAJOR}_SOURCES} 9 | - LIBRARIES ${HAVE_LIBSYSTEMCONFIGURATION} 10 | + LIBRARIES ${HAVE_LIBSYSTEMCONFIGURATION} "-framework CoreFoundation" 11 | ) 12 | 13 | # Linux-only extensions 14 | -------------------------------------------------------------------------------- /source/projects/py/resources/pyjs-dependencies.txt: -------------------------------------------------------------------------------- 1 | # place common python3 dependencies here 2 | # used for actions/cache@v3 in github workflows 3 | # this file is hashed and used as a key 4 | # if anything changes in this file, included comments, 5 | # the cache will be reset 6 | bzip2-1.0.8.tar.gz 7 | openssl-1.1.1n.tar.gz 8 | xz-5.2.5.tar.gz 9 | 10 | -------------------------------------------------------------------------------- /source/projects/py/resources/workflows/workflows.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/py/resources/workflows/workflows.zip -------------------------------------------------------------------------------- /source/projects/py/scripts/analyze.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | def otool(name, path): 5 | # terminal codes 6 | WHITE = "\x1b[97;20m" 7 | RESET = "\x1b[0m" 8 | print('-'*79) 9 | print(f'{WHITE}{name} {path.stem} dependencies{RESET}') 10 | os.system(f'otool -L {path}') 11 | 12 | def analyze(): 13 | for d in Path.cwd().iterdir(): 14 | if d.is_dir(): 15 | if d.stem.endswith('-pkg'): 16 | py = d / 'externals' / 'py.mxo' / 'Contents' / 'MacOS' / 'py' 17 | pyjs = d / 'externals' / 'pyjs.mxo' / 'Contents' / 'MacOS' / 'pyjs' 18 | else: 19 | py = d / 'py.mxo' / 'Contents' / 'MacOS' / 'py' 20 | pyjs = d / 'pyjs.mxo' / 'Contents' / 'MacOS' / 'pyjs' 21 | otool(d.stem, py) 22 | otool(d.stem, pyjs) 23 | 24 | 25 | if __name__ == '__main__': 26 | analyze() -------------------------------------------------------------------------------- /source/projects/py/scripts/b64.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | def encode(s: str): 4 | s_bytes = s.encode("ascii") 5 | s_bytes_b64 = base64.b64encode(s_bytes) 6 | s_b64 = s_bytes_b64.decode("ascii") 7 | print("original length:", len(s)) 8 | print(f"encoded: {s_b64}") 9 | print("encoded length:", len(s_b64)) 10 | print("increase factor:", len(s_b64)/len(s)) 11 | return s_b64 12 | 13 | def decode(s_b64: str): 14 | s_bytes_b64 = s_b64.encode("ascii") 15 | s_bytes = base64.b64decode(s_bytes_b64) 16 | s = s_bytes.decode("ascii") 17 | print(f"decoded: {s}") 18 | return s 19 | 20 | py_module = """ 21 | import base64 22 | 23 | def encode(s: str): 24 | s_bytes = s.encode("ascii") 25 | s_bytes_b64 = base64.b64encode(s_bytes) 26 | s_b64 = s_bytes_b64.decode("ascii") 27 | print(f"encoded: {s_b64}") 28 | return s_b64 29 | 30 | def decode(s_b64: str): 31 | s_bytes_b64 = s_b64.encode("ascii") 32 | s_bytes = base64.b64decode(s_bytes_b64) 33 | s = s_bytes.decode("ascii") 34 | print(f"decoded: {s}") 35 | return s 36 | """ 37 | 38 | s_b64 = encode(py_module) 39 | s = decode(s_b64) 40 | assert s == py_module 41 | -------------------------------------------------------------------------------- /source/projects/py/scripts/bash_complete.sh: -------------------------------------------------------------------------------- 1 | # makefile completion: source this file 2 | complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'\`" make 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/scripts/build_dev.sh: -------------------------------------------------------------------------------- 1 | rm -rf ./build ./externals 2 | 3 | pushd . 4 | 5 | mkdir build 6 | cd build 7 | cmake .. \ 8 | -DBUILD_PYTHON3_CORE_EXTERNALS=ON \ 9 | -DBUILD_PYTHON3_EXPERIMENTAL_EXTERNALS=ON \ 10 | -DBUILD_POCKETPY_EXTERNALS=ON \ 11 | -DBUILD_DEMO_EXTERNALS=ON 12 | make 13 | cd .. 14 | make sign 15 | 16 | popd 17 | 18 | -------------------------------------------------------------------------------- /source/projects/py/scripts/build_projects.sh: -------------------------------------------------------------------------------- 1 | rm -rf ./build ./externals 2 | 3 | pushd . 4 | 5 | mkdir build 6 | cd build 7 | cmake -GXcode .. 8 | cmake --build . --config Release 9 | 10 | popd 11 | 12 | -------------------------------------------------------------------------------- /source/projects/py/scripts/build_universal.sh: -------------------------------------------------------------------------------- 1 | # This doesn't work unless dependencies are also fat binaries 2 | 3 | rm -rf ./build ./externals 4 | 5 | pushd . 6 | 7 | mkdir build 8 | cd build 9 | cmake -G Xcode .. 10 | cmake --build . 11 | 12 | popd 13 | 14 | -------------------------------------------------------------------------------- /source/projects/py/scripts/check-big-git-files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -x 3 | 4 | # Shows you the largest objects in your repo's pack file. 5 | # Written for osx. 6 | # @see http://bit.ly/UmpwkV/ 7 | # @author Antony Stubbs 8 | 9 | # set the internal field separator to line break, 10 | # so that we can iterate easily over the verify-pack output 11 | IFS=$'\n'; 12 | 13 | # list all objects including their size, sort by size, take top 10 14 | objects=`git verify-pack -v .git/objects/pack/pack-*.idx | \ 15 | grep -v chain | sort -k3nr | head` 16 | 17 | echo "All sizes are in kB's. The pack column is the size of the object, \ 18 | compressed, inside the pack file." 19 | 20 | output="size,pack,SHA,location" 21 | for y in $objects 22 | do 23 | # extract the size in bytes 24 | size=$((`echo $y | cut -f 5 -d ' '`/1024)) 25 | # extract the compressed size in bytes 26 | compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024)) 27 | # extract the SHA 28 | sha=`echo $y | cut -f 1 -d ' '` 29 | # find the objects location in the repository tree 30 | other=`git rev-list --all --objects | grep $sha` 31 | #lineBreak=`echo -e "\n"` 32 | output="${output}\n${size},${compressedSize},${other}" 33 | done 34 | 35 | echo -e $output | column -t -s ', ' 36 | 37 | -------------------------------------------------------------------------------- /source/projects/py/scripts/check_numpy.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | scripts to get numpy include and test if it exists 4 | 5 | """ 6 | 7 | import argparse 8 | import sys 9 | 10 | try: 11 | import numpy 12 | NUMPY_INCLUDE = numpy.get_include() 13 | except ImportError: 14 | NUMPY_INCLUDE = None 15 | 16 | 17 | 18 | parser = argparse.ArgumentParser() 19 | parser.add_argument('--include', action='store_true', help='get numpy_include') 20 | parser.add_argument('--exists', action='store_true', help='check if numpy exists') 21 | 22 | args = parser.parse_args() 23 | if args.include: 24 | if NUMPY_INCLUDE: 25 | print(NUMPY_INCLUDE) 26 | sys.exit() 27 | if args.exists: 28 | if NUMPY_INCLUDE: 29 | print(1) 30 | else: 31 | print(0) 32 | 33 | -------------------------------------------------------------------------------- /source/projects/py/scripts/cmake-pyjs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | ############################################################# 4 | # MAX EXTERNAL 5 | ############################################################# 6 | 7 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") 8 | 9 | find_package(Python3 COMPONENTS Interpreter Development) 10 | 11 | include_directories( 12 | "${MAX_SDK_INCLUDES}" 13 | "${MAX_SDK_MSP_INCLUDES}" 14 | "${MAX_SDK_JIT_INCLUDES}" 15 | 16 | "${Python3_INCLUDE_DIRS}" 17 | ) 18 | 19 | file(GLOB PROJECT_SRC 20 | "*.h" 21 | "*.c" 22 | "*.cpp" 23 | ) 24 | 25 | add_library( 26 | ${PROJECT_NAME} 27 | MODULE 28 | ${PROJECT_SRC} 29 | ) 30 | 31 | target_link_directories( 32 | ${PROJECT_NAME} 33 | PRIVATE 34 | "${Python3_LIBRARY_DIRS}" 35 | ) 36 | 37 | 38 | target_link_libraries( 39 | ${PROJECT_NAME} 40 | PRIVATE 41 | "${Python3_LIBRARIES}" 42 | "-ldl" 43 | "-framework CoreFoundation" 44 | ) 45 | 46 | 47 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 48 | -------------------------------------------------------------------------------- /source/projects/py/scripts/entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.allow-unsigned-executable-memory 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /source/projects/py/scripts/fix-pyjs-standalone.sh: -------------------------------------------------------------------------------- 1 | STANDALONE=$1 2 | ARCH=`uname -m` 3 | 4 | fix_pyjs_standalone() { 5 | cp -rf javascript $1/Contents/Resources/C74 6 | cp -rf jsextensions $1/Contents/Resources/C74 7 | cp -af externals/pyjs.mxo $1/Contents/Resources/C74/externals 8 | } 9 | 10 | echo "fixing pyjs standalone" 11 | fix_pyjs_standalone ${STANDALONE} 12 | -------------------------------------------------------------------------------- /source/projects/py/scripts/rm_disabled_workflow_runs.sh: -------------------------------------------------------------------------------- 1 | org=shakfu 2 | repo=py-js 3 | 4 | # Get workflow IDs with status "disabled_manually" 5 | workflow_ids=($(gh api repos/$org/$repo/actions/workflows | jq '.workflows[] | select(.["state"] | contains("disabled_manually")) | .id')) 6 | 7 | for workflow_id in "${workflow_ids[@]}" 8 | do 9 | echo "Listing runs for the workflow ID $workflow_id" 10 | run_ids=( $(gh api repos/$org/$repo/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') ) 11 | for run_id in "${run_ids[@]}" 12 | do 13 | echo "Deleting Run ID $run_id" 14 | gh api repos/$org/$repo/actions/runs/$run_id -X DELETE >/dev/null 15 | done 16 | done 17 | 18 | -------------------------------------------------------------------------------- /source/projects/py/scripts/set_py_ver.py: -------------------------------------------------------------------------------- 1 | import os 2 | import platform 3 | 4 | env_file = os.getenv('GITHUB_ENV') 5 | #env_file = 'env.log' 6 | 7 | python_version = platform.python_version() 8 | 9 | if env_file: 10 | with open(env_file, "a") as fopen: 11 | fopen.write(f"PY_VERSION={python_version}") 12 | else: 13 | raise KeyError("'GITHUB_ENV' env var not set") 14 | -------------------------------------------------------------------------------- /source/projects/py/scripts/standalone/build-standalone.txt: -------------------------------------------------------------------------------- 1 | open thispatcher include "VOLE:/Users/sa/Documents/Max 8/Packages/py/externals/pyjs.mxo" -------------------------------------------------------------------------------- /source/projects/py/scripts/standalone/custom/jsextensions/maxclasswrap.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Wraps the pyjs external for use by the js object in max 4 | 5 | */ 6 | 7 | maxclasswrap("pyjs","PyJS"); 8 | 9 | -------------------------------------------------------------------------------- /source/projects/py/scripts/stripw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | 5 | filename = sys.argv[1] 6 | 7 | with open(filename) as f: 8 | lines = [line.rstrip() for line in f.readlines()] 9 | with open('cleaned_'+filename, 'w') as g: 10 | g.write("\n".join(lines)) 11 | 12 | -------------------------------------------------------------------------------- /source/projects/py/targets/beeware-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | 4 | PREFIX = $(PYJS_BUILD_LIB)/python-beeware 5 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 6 | 7 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 8 | 9 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto -lffi -lsqlite3 10 | 11 | //FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" "$(PYJS_BUILD_LIB)" 12 | -------------------------------------------------------------------------------- /source/projects/py/targets/beeware-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | 4 | PREFIX = $(PYJS_BUILD_LIB)/Python 5 | 6 | Python = $(PREFIX)/Python 7 | BZip2 = $(PREFIX)/BZip2 8 | OpenSSL = $(PREFIX)/OpenSSL 9 | XZ = $(PREFIX)/XZ 10 | 11 | PY_HEADERS = $(Python)/Headers $(BZip2)/Headers $(OpenSSL)/Headers $(XZ)/Headers 12 | PY_LIBS = $(Python) $(BZip2) $(OpenSSL) $(XZ) 13 | PY_LDFLAGS = -ldl -lsqlite3 -lffi -llzma -lz 14 | 15 | //PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 16 | //PY_LIBS = $(PREFIX)/lib 17 | //PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 18 | -------------------------------------------------------------------------------- /source/projects/py/targets/framework-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PY_LOCAL = $(HOME)/Downloads/projects/py-js/source/py/targets/build/lib 4 | 5 | PREFIX = $(PYJS_BUILD_LIB)/Python.framework/Versions/${VERSION} 6 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 7 | PY_LIBS = $(PREFIX)/lib 8 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 9 | 10 | // to enable compilation for arm64 (or change manually in xcode) 11 | FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" "$(PYJS_BUILD_LIB)" 12 | 13 | -------------------------------------------------------------------------------- /source/projects/py/targets/framework-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(SUPPORT)/Python.framework/Versions/$(VERSION) 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib 6 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 7 | 8 | // to enable compilation for arm64 (or change manually in xcode) 9 | FRAMEWORK_SEARCH_PATH = $(inherited) $(PYJS_BUILD_LIB) 10 | -------------------------------------------------------------------------------- /source/projects/py/targets/homebrew-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(SUPPORT)/python$(VERSION) 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX) 6 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 7 | 8 | //OTHER_CODE_SIGN_FLAGS = --deep 9 | 10 | //FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" "$(PYJS_BUILD_LIB)" 11 | -------------------------------------------------------------------------------- /source/projects/py/targets/homebrew-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(SUPPORT)/Python.framework/Versions/$(VERSION) 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib 6 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 7 | 8 | // to enable compilation for arm64 (or change manually in xcode) 9 | FRAMEWORK_SEARCH_PATH = $(inherited) $(PYJS_BUILD_LIB) 10 | -------------------------------------------------------------------------------- /source/projects/py/targets/local-sys/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This is overriden by the builder from the commandline build 4 | PREFIX = /Library/Frameworks/Python.framework/Versions/$(VERSION) 5 | 6 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 7 | PY_LIBS = $(PREFIX)/lib 8 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) 9 | -------------------------------------------------------------------------------- /source/projects/py/targets/optimize.xcconfig: -------------------------------------------------------------------------------- 1 | // Optimization / Stripping Section 2 | 3 | 4 | 5 | OPTIM_LINK_FLAGS = "-Xlinker -x" 6 | DEPLOYMENT_POSTPROCESSING = YES 7 | // Whether to strip debugging symbols when copying resources (like included binaries) 8 | COPY_PHASE_STRIP = YES 9 | // Whether to compile assertions in. 10 | ENABLE_NS_ASSERTIONS = NO 11 | // The optimization level (0, 1, 2, 3, s) for the produced binary 12 | GCC_OPTIMIZATION_LEVEL = s 13 | // Preproccessor definitions to apply to each file compiled 14 | GCC_PREPROCESSOR_DEFINITIONS = NDEBUG=1 15 | // Whether to enable link-time optimizations (such as inlining across translation units) 16 | LLVM_LTO = NO 17 | // Whether to strip debugging symbols when copying the built product to its final installation location 18 | STRIP_INSTALLED_PRODUCT = YES 19 | DEAD_CODE_STRIPPING = YES 20 | 21 | // Any option below causes build failure 22 | // STRIP_STYLE = -x 23 | // STRIP_STYLE = -s 24 | // STRIP_STYLE = -S 25 | 26 | OTHER_LDFLAGS = $(inherited) $(OPTIM_LINK_FLAGS) 27 | 28 | -------------------------------------------------------------------------------- /source/projects/py/targets/relocatable-pkg/.gitignore: -------------------------------------------------------------------------------- 1 | Python.framework/ 2 | -------------------------------------------------------------------------------- /source/projects/py/targets/relocatable-pkg/README.md: -------------------------------------------------------------------------------- 1 | # Relocatable Framework Pkg 2 | 3 | A variation using Gleg Neagle's [Relocatable Python](https://github.com/gregneagle/relocatable-python) 4 | 5 | Uses @rpath and requires that `LD_RUNPATH_SEARCH_PATHS` is set in xcode to the right back ref, currently to: 6 | 7 | ```text 8 | 9 | LD_RUNPATH_SEARCH_PATHS = @loader_path/../../../../support/Python.framework 10 | 11 | ``` 12 | 13 | Tested as relocatable and works well for the Framework-pkg case. 14 | -------------------------------------------------------------------------------- /source/projects/py/targets/relocatable-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | 4 | PREFIX = $(SUPPORT)/Python.framework/Versions/$(VERSION) 5 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 6 | PY_LIBS = $(PREFIX)/lib 7 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 8 | 9 | // same value as below set in build settings > run path settings 10 | // somehow not picking it up from here?! 11 | //LD_RUNPATH_SEARCH_PATHS = @loader_path/../../../../support/Python.framework 12 | //FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" "$(SUPPORT)" 13 | -------------------------------------------------------------------------------- /source/projects/py/targets/shared-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(PYJS_BUILD_LIB)/python-shared 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 6 | 7 | // pre-patch 8 | // PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lintl -liconv 9 | 10 | // post-patch 11 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz 12 | -------------------------------------------------------------------------------- /source/projects/py/targets/shared-pkg/build.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Running this with a particular python version will auto-config py-js.xcconfig 4 | 5 | 6 | """ 7 | 8 | import sysconfig 9 | import os 10 | 11 | 12 | def xcodebuild(project_path: str, target: str, *preprocessor_flags, **xcconfig_flags): 13 | """python wrapper around command-line xcodebuild""" 14 | x_flags = " ".join([f"{k}={repr(v)}" for k,v in xcconfig_flags.items()]) if xcconfig_flags else '' 15 | p_flags = "GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS {flags}'".format( 16 | flags=" ".join([f"{k}=1" for k in preprocessor_flags])) if preprocessor_flags else '' 17 | _cmd = f"xcodebuild -project {repr(project_path)} -target {repr(target)} {x_flags} {p_flags}" 18 | print(_cmd) 19 | os.system(_cmd) 20 | 21 | 22 | flags = dict( 23 | VERSION = sysconfig.get_config_var('py_version_short'), 24 | SUFFIX = sysconfig.get_config_var('abiflags'), 25 | ) 26 | 27 | for t in ['py', 'pyjs']: 28 | xcodebuild('py-js.xcodeproj', t, **flags) 29 | -------------------------------------------------------------------------------- /source/projects/py/targets/shared-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | 4 | PREFIX = $(SUPPORT)/python$(VERSION) 5 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 6 | PY_LIBS = $(PREFIX)/lib 7 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 8 | -------------------------------------------------------------------------------- /source/projects/py/targets/static-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | 4 | PREFIX = $(PYJS_BUILD_LIB)/python-static 5 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 6 | 7 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 8 | 9 | // pre-patch 10 | // PY_LDFLAGS = -lpython$(VERSION) -ldl -lssl -lbz2 -llzma -lz -liconv 11 | 12 | // post-patch 13 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 14 | -------------------------------------------------------------------------------- /source/projects/py/targets/static-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(SUPPORT)/python$(VERSION) 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib 6 | 7 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 8 | 9 | // old (with gettext dependency) 10 | //PY_LIBS = $(PREFIX)/lib /usr/local/Cellar/gettext/0.21/lib 11 | //PY_LDFLAGS = -lpython$(VERSION) -ldl -lintl 12 | 13 | -------------------------------------------------------------------------------- /source/projects/py/targets/vanilla-ext/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(PYJS_BUILD_LIB)/Python.framework/Versions/${VERSION} 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib 6 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 7 | 8 | // to enable compilation for arm64 (or change manually in xcode) 9 | FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" "$(PYJS_BUILD_LIB)" 10 | -------------------------------------------------------------------------------- /source/projects/py/targets/vanilla-pkg/py-js.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | PREFIX = $(SUPPORT)/Python.framework/Versions/$(VERSION) 4 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 5 | PY_LIBS = $(PREFIX)/lib 6 | PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl 7 | 8 | // to enable compilation for arm64 (or change manually in xcode) 9 | FRAMEWORK_SEARCH_PATH = $(inherited) $(PYJS_BUILD_LIB) 10 | 11 | // also HEADER_SEARCH_PATH must include $(PY_HEADERS) 12 | 13 | // set build architecture arm64 for native apple silicon -------------------------------------------------------------------------------- /source/projects/py/targets/xg-demo/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-demo/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-demo/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.13 5 | ABIFLAGS = 6 | PREFIX = /opt/homebrew/opt/python@$(VERSION)/Frameworks/Python.framework/Versions/$(VERSION) 7 | NUMPY_HEADERS = 8 | 9 | // -------------------------------------------------------------------------------- 10 | 11 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) $(NUMPY_HEADERS) 12 | PY_LIBS = $(PREFIX)/lib 13 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) 14 | 15 | PROJECT_HEADERS = $(PY_HEADERS) 16 | PROJECT_LIBS = $(PY_LIBS) 17 | PROJECT_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) 18 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-demo/project.yml: -------------------------------------------------------------------------------- 1 | name: demo 2 | options: 3 | bundleIdPrefix: org.me 4 | settings: 5 | ARCHS: $(NATIVE_ARCH) 6 | MACOSX_DEPLOYMENT_TARGET: "10.13" 7 | CODE_SIGN_IDENTITY: "-" 8 | DEVELOPMENT_TEAM: "" 9 | GCC_OPTIMIZATION_LEVEL: 0 10 | GCC_NO_COMMON_BLOCKS: No 11 | HEADER_SEARCH_PATHS: 12 | - $(C74SUPPORT)/max-includes 13 | - $(C74SUPPORT)/msp-includes 14 | - $(C74SUPPORT)/jit-includes 15 | - $(PROJECT_HEADERS) 16 | INFOPLIST_FILE: $(SRCROOT)/../../../Info.plist 17 | LIBRARY_SEARCH_PATHS: $(PROJECT_LIBS) 18 | OTHER_LDFLAGS: 19 | - $(C74_SYM_LINKER_FLAGS) 20 | - $(MSP_JIT_LDFLAGS) 21 | - $(PROJECT_LDFLAGS) 22 | PRODUCT_NAME: $(TARGET_NAME) 23 | configFiles: 24 | Debug: project.xcconfig 25 | Release: project.xcconfig 26 | 27 | targets: 28 | py: 29 | type: bundle 30 | platform: macOS 31 | sources: 32 | - ../../py.c 33 | - ../../api.c 34 | dependencies: 35 | - sdk: CoreFoundation.framework 36 | 37 | pyjs: 38 | type: bundle 39 | platform: macOS 40 | sources: 41 | - ../../pyjs.c 42 | dependencies: 43 | - sdk: CoreFoundation.framework 44 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-framework-ext/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-framework-ext/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-framework-ext/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.11 5 | ABIFLAGS = 6 | PREFIX = $(PYJS_BUILD_LIB)/python-shared 7 | 8 | // -------------------------------------------------------------------------------- 9 | 10 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 11 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 12 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 13 | 14 | //PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz 15 | 16 | PROJECT_HEADERS = $(PY_HEADERS) 17 | PROJECT_LIBS = $(PY_LIBS) 18 | PROJECT_LDFLAGS = $(PY_LDFLAGS) 19 | 20 | 21 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-3.7/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-3.7/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-3.7/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.11 5 | ABIFLAGS = 6 | PREFIX = $(PYJS_BUILD_LIB)/python-shared 7 | 8 | // -------------------------------------------------------------------------------- 9 | 10 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 11 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 12 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 13 | 14 | //PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz 15 | 16 | PROJECT_HEADERS = $(PY_HEADERS) 17 | PROJECT_LIBS = $(PY_LIBS) 18 | PROJECT_LDFLAGS = $(PY_LDFLAGS) 19 | 20 | 21 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-ext/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-ext/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-shared-ext/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.11 5 | ABIFLAGS = 6 | PREFIX = $(PYJS_BUILD_LIB)/python-shared 7 | 8 | // -------------------------------------------------------------------------------- 9 | 10 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 11 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 12 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 13 | 14 | //PY_LDFLAGS = -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz 15 | 16 | PROJECT_HEADERS = $(PY_HEADERS) 17 | PROJECT_LIBS = $(PY_LIBS) 18 | PROJECT_LDFLAGS = $(PY_LDFLAGS) 19 | 20 | 21 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-3.7/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-3.7/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-3.7/build.sh: -------------------------------------------------------------------------------- 1 | PROJECT="py-js" 2 | XCODEPROJ=${PROJECT}.xcodeproj 3 | HELPFILE=${PROJECT}.maxhelp 4 | TARGETS="py pyjs" 5 | 6 | if [[ -d ${XCODEPROJ} ]] 7 | then 8 | rm -rf ${XCODEPROJ} 9 | fi 10 | VERSION=3.7 VER_MINOR=7 xcodegen 11 | 12 | for t in ${TARGETS} 13 | do 14 | xcodebuild -project ${XCODEPROJ} -target $t 15 | done 16 | 17 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-3.7/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.7 5 | VER_MINOR = 7 6 | ABIFLAGS = m 7 | PREFIX = $(PYJS_BUILD_LIB)/python-static 8 | 9 | // -------------------------------------------------------------------------------- 10 | 11 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 12 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 13 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 14 | 15 | PROJECT_HEADERS = $(PY_HEADERS) 16 | PROJECT_LIBS = $(PY_LIBS) 17 | PROJECT_LDFLAGS = $(PY_LDFLAGS) 18 | 19 | 20 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-ext/.gitignore: -------------------------------------------------------------------------------- 1 | py-js.xcodeproj 2 | build 3 | 4 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-ext/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = py pyjs 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | pyjs: generate 17 | xcodebuild -project $(XCODEPROJ) -target pyjs 18 | 19 | 20 | build: generate 21 | @for t in $(TARGETS) ; do \ 22 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 23 | done 24 | 25 | clean: 26 | @rm -rf $(XCODEPROJ) build 27 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-ext/build.sh: -------------------------------------------------------------------------------- 1 | PROJECT="py-js" 2 | XCODEPROJ=${PROJECT}.xcodeproj 3 | HELPFILE=${PROJECT}.maxhelp 4 | TARGETS="py pyjs" 5 | 6 | if [[ -d ${XCODEPROJ} ]] 7 | then 8 | rm -rf ${XCODEPROJ} 9 | fi 10 | VERSION=3.11 VER_MINOR=11 xcodegen 11 | 12 | for t in ${TARGETS} 13 | do 14 | xcodebuild -project ${XCODEPROJ} -target $t 15 | done 16 | 17 | -------------------------------------------------------------------------------- /source/projects/py/targets/xg-static-ext/project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../common.xcconfig" 2 | 3 | // This can overriden by the builder at the commandline build 4 | VERSION = 3.11 5 | ABIFLAGS = 6 | PREFIX = $(PYJS_BUILD_LIB)/python-static 7 | 8 | // -------------------------------------------------------------------------------- 9 | 10 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) 11 | PY_LIBS = $(PREFIX)/lib $(PYJS_BUILD_LIB)/bzip2/lib $(PYJS_BUILD_LIB)/openssl/lib $(PYJS_BUILD_LIB)/xz/lib 12 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) -ldl -lssl -lbz2 -llzma -lz -lcrypto 13 | 14 | PROJECT_HEADERS = $(PY_HEADERS) 15 | PROJECT_LIBS = $(PY_LIBS) 16 | PROJECT_LDFLAGS = $(PY_LDFLAGS) 17 | 18 | 19 | -------------------------------------------------------------------------------- /source/projects/py/tests/_old/test_goto.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int x = 10; 6 | // fall through with no return! 7 | 8 | hello: 9 | x++; 10 | printf("hello: %d\n", x); 11 | 12 | bye: 13 | x++; 14 | printf("bye: %d\n", x); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /source/projects/py/tests/_old/test_print.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void printf2(char* fmt, ...) 5 | { 6 | va_list args; 7 | va_start(args, fmt); 8 | vprintf(fmt, args); 9 | va_end(args); 10 | } 11 | 12 | void sprintf2(char* buf, char* fmt, ...) 13 | { 14 | va_list va; 15 | va_start(va, fmt); 16 | vsprintf(buf, fmt, va); 17 | va_end(va); 18 | } 19 | 20 | void test_sprintf2(void) 21 | { 22 | char buff[100]; 23 | sprintf2(buff, "Hello, %s, aged %d", "Jo", 27); 24 | printf("%s\n", buff); 25 | } 26 | 27 | int main() 28 | { 29 | printf("printf: hello %d\n", 1); 30 | printf2("printf2: hello %d\n", 1); 31 | test_sprintf2(); 32 | } -------------------------------------------------------------------------------- /source/projects/py/tests/_old/test_string.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | char *foo(int count) { 7 | char *ret = malloc(count); 8 | if(!ret) 9 | return NULL; 10 | 11 | for(int i = 0; i < count; ++i) 12 | ret[i] = i; 13 | 14 | return ret; 15 | } 16 | 17 | 18 | 19 | void doit(char *buf, int count) { 20 | for(int i = 0; i < count; ++i) 21 | buf[i] = i; 22 | } 23 | 24 | 25 | int main() 26 | { 27 | char txt[10] = {0}; 28 | char txt1[50] = "Hello World"; 29 | char* txt2 = "World Hello"; 30 | char** p_txt = &txt2; 31 | doit(txt, 10); 32 | 33 | char *p = foo(10); 34 | if(p) { 35 | printf("p: %s length: %ld\n", p, strlen(p)); 36 | free(p); 37 | } 38 | 39 | printf("txt1: %s length: %ld\n", txt1, strlen(txt1)); 40 | printf("txt2: %s length: %ld\n", txt2, strlen(txt2)); 41 | printf("p_txt: %s length: %ld\n", *p_txt, strlen(*p_txt)); 42 | printf("txt: %s length: %ld\n", txt, strlen(txt)); 43 | } -------------------------------------------------------------------------------- /source/projects/py/tests/build.sh: -------------------------------------------------------------------------------- 1 | # see: https://stackoverflow.com/questions/27672572/embedding-python-in-c-linking-fails-with-undefined-reference-to-py-initialize 2 | 3 | 4 | echo "compiling..." 5 | 6 | for fname in $@ 7 | do 8 | echo "compiling $fname" 9 | bname=$(basename $fname .c) 10 | if [[ "$OSTYPE" == "linux-gnu"* ]]; then 11 | clang -g -I /usr/include/python3.10 -lpython3.10 $fname -o $bname 12 | elif [[ "$OSTYPE" == "darwin"* ]]; then 13 | gcc -g `python3-config --cflags --ldflags` -lpython3.10 $fname -o $bname 14 | else 15 | echo "not implemented" 16 | fi 17 | done 18 | 19 | echo "cleaning up..." 20 | rm -rf *.dSYM 21 | 22 | -------------------------------------------------------------------------------- /source/projects/py/tests/build_noxcode/test_mxsdk.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "ext.h" 5 | #include "ext_obex.h" 6 | 7 | int main() 8 | { 9 | // printf() displays the string inside quotation 10 | post("HELLO"); 11 | printf("Hello, Max!"); 12 | return 0; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /source/projects/py/tests/codecheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | infer run -- gcc -g `python3-config --cflags --ldflags` -lpython3.9 $1 -o $(basename $1 .c) 4 | -------------------------------------------------------------------------------- /source/projects/py/tests/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | join = os.path.join 4 | cwd = os.getcwd() 5 | 6 | -------------------------------------------------------------------------------- /source/projects/py/tests/debug.sh: -------------------------------------------------------------------------------- 1 | 2 | clang -g -std=c99 -ggdb3 -O0 -pedantic-errors -Wall -Wextra \ 3 | -fpie $(python3.9-config --cflags --embed) -o $1 \ 4 | $1.c $(python3.9-config --embed --ldflags) 5 | 6 | 7 | -------------------------------------------------------------------------------- /source/projects/py/tests/fourchar.py: -------------------------------------------------------------------------------- 1 | 2 | def fourchar(code: str) -> int: 3 | """Convert fourc chars to an int 4 | 5 | >>> fourchar('HUVL') 6 | 1213552204 7 | """ 8 | assert len(code) == 4, "should be four characters only" 9 | return ((ord(code[0]) << 24) | (ord(code[1]) << 16) | 10 | (ord(code[2]) << 8) | ord(code[3])) 11 | -------------------------------------------------------------------------------- /source/projects/py/tests/prelude/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: all build test 3 | 4 | all: build 5 | 6 | build: 7 | uv build 8 | 9 | test: 10 | uv run pytest 11 | -------------------------------------------------------------------------------- /source/projects/py/tests/python_cmake_buildsystem/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONEY: build log clean 3 | 4 | all: build 5 | 6 | 7 | build: clean 8 | python3 build.py 9 | 10 | log: clean 11 | python3 build.py &> run.log 12 | 13 | 14 | clean: 15 | @rm -rf python-cmake* 16 | @rm -rf Python* 17 | @rm -f run.log 18 | -------------------------------------------------------------------------------- /source/projects/py/tests/python_cmake_buildsystem/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PREFIX=${PWD}/work 4 | SRC_DIR=${PREFIX}/src 5 | BUILD_DIR=${PREFIX}/build 6 | INSTALL_DIR=${PREFIX}/install 7 | 8 | git clone --depth=1 https://github.com/shakfu/python-cmake-buildsystem ${SRC_DIR} 9 | cmake -S ${SRC_DIR} -B ${BUILD_DIR} \ 10 | -DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_DIR} \ 11 | -DBUILD_LIBPYTHON_SHARED:BOOL=YES 12 | cmake --build ${BUILD_DIR} 13 | cmake --install ${BUILD_DIR} 14 | ${INSTALL_DIR}/bin/python -m test 15 | 16 | -------------------------------------------------------------------------------- /source/projects/py/tests/python_cmake_buildsystem/scproxy.patch: -------------------------------------------------------------------------------- 1 | 206c206 2 | < LIBRARIES ${HAVE_LIBSYSTEMCONFIGURATION} 3 | --- 4 | > LIBRARIES ${HAVE_LIBSYSTEMCONFIGURATION} "-framework CoreFoundation" 5 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_clip_assign.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define CLIP_ASSIGN(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) 5 | 6 | 7 | // gcc -E test_clip_assign.c 8 | // gcc -o tesT_clip test_clip_assign.c 9 | 10 | 11 | int clamp(int x, int min, int max) 12 | { 13 | if (x < min) 14 | return min; 15 | if (x > max) 16 | return max; 17 | return x; 18 | } 19 | 20 | int main() 21 | { 22 | int argc = 10; 23 | int dim0 = 5; 24 | int dim1 = 5; 25 | int offset0 = 0; 26 | int offset1 = 1; 27 | 28 | CLIP_ASSIGN(argc, 0, (dim0 * (dim1 - offset1)) - offset0); 29 | 30 | printf("argc = %d\n", argc); 31 | 32 | argc = clamp(argc, 0, (dim0 * (dim1 - offset1)) - offset0); 33 | 34 | printf("argc = %d\n", argc); 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_cwd.c: -------------------------------------------------------------------------------- 1 | #include /* defines FILENAME_MAX */ 2 | #ifdef WINDOWS 3 | #include 4 | #define get_current_dir _getcwd 5 | #else 6 | #include 7 | #define get_current_dir getcwd 8 | #endif 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | char current_path[FILENAME_MAX]; 13 | 14 | if (!get_current_dir(current_path, sizeof(current_path))) { 15 | // return errno; 16 | return 1; 17 | } 18 | 19 | current_path[sizeof(current_path) - 1] = '\0'; /* not really required */ 20 | 21 | printf("The current working directory is %s", current_path); 22 | return 0; 23 | } 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_dict.py: -------------------------------------------------------------------------------- 1 | """ 2 | goose : honk pig : 0.05 frog : -8 horse : 1 2 foo 3 duck : "quack quack" 3 | 4 | """ 5 | def pydict_to_mxdict(d): 6 | res = [] 7 | for k,v in d.items(): 8 | res.append(k) 9 | res.append(':') 10 | if type(v) in [list, set, tuple]: 11 | for i in v: 12 | res.append(i) 13 | else: 14 | res.append(v) 15 | return res 16 | 17 | 18 | def test_pydict_to_mxdict(): 19 | d = dict(a='b', c=1.2, d=[1, 2, 34]) 20 | assert " ".join(pydict_to_mxdict(d)) == 'a : b c : 1.2 d : 1 2 34' 21 | 22 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_generics.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // clang -std=c11 -o test_generics test_generics.c 4 | 5 | void print_int(int); 6 | void print_float(float); 7 | 8 | #define print(x) _Generic((x), int: print_int(x), float: print_float(x)) 9 | 10 | 11 | void print_int(int n) { printf("this is an int: %i\n", n); } 12 | 13 | void print_float(float n) { printf("this is a float: %f\n", n); } 14 | 15 | 16 | int main(int argc, char* argv[]) 17 | { 18 | int i = 10; 19 | float f = 5.5; 20 | 21 | print(i); 22 | print(f); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_matrix_flattern.c: -------------------------------------------------------------------------------- 1 | // from: https://stackoverflow.com/questions/71641582/flattening-a-2d-array-in-c-without-malloc-etc 2 | #include 3 | #include 4 | 5 | #define ROWS 5 6 | #define COLS 15 7 | 8 | int main() { 9 | unsigned short i, j; 10 | int ar[ROWS][COLS]; 11 | int flat_array [ROWS * COLS]; 12 | puts ("2D array: "); 13 | for (i = 0; i < ROWS; i++) { 14 | for (j = 0; j < COLS; j++) { 15 | ar[i][j] = rand() % 10; 16 | flat_array[COLS * i + j] = ar[i][j]; 17 | printf ("%d ", ar[i][j]); 18 | } 19 | printf ("\n"); 20 | } 21 | printf("\nFlattened Array: \n"); 22 | for (int fi = 0; fi < ROWS * COLS; ) 23 | printf ("%d ", flat_array[fi++]); 24 | 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_minim.c: -------------------------------------------------------------------------------- 1 | #define PY_SSIZE_T_CLEAN 2 | #include 3 | 4 | int main(int argc, char *argv[]) { 5 | (void)argc; 6 | wchar_t *program = Py_DecodeLocale(argv[0], NULL); 7 | if (program == NULL) { 8 | fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); 9 | exit(1); 10 | } 11 | Py_SetProgramName(program); 12 | Py_Initialize(); 13 | PyRun_SimpleString(argv[1]); 14 | if (Py_FinalizeEx() < 0) { 15 | exit(120); 16 | } 17 | PyMem_RawFree(program); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /source/projects/py/tests/test_pyver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // gcc -o test_pver test_pyver.c -I `python3-config --include` 5 | 6 | #define _STR(x) #x 7 | #define STR(x) _STR(x) 8 | #define _CONCAT(a, b) a##b 9 | #define CONCAT(a, b) _CONCAT(a, b) 10 | #define _PY_VER CONCAT(PY_MAJOR_VERSION, CONCAT(., PY_MINOR_VERSION)) 11 | #define PY_VER STR(_PY_VER) 12 | 13 | #define VER STR(PY_MAJOR_VERSION) "." STR(PY_MINOR_VERSION) 14 | 15 | 16 | 17 | int main() 18 | { 19 | printf("pyver: " PY_VER "\n"); 20 | printf("ver: " STR(PY_MAJOR_VERSION) "." STR(PY_MINOR_VERSION) "\n"); 21 | printf("ver: " VER "\n"); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /source/projects/py/tests/test_to_dict.py: -------------------------------------------------------------------------------- 1 | from builder.factory import builder_factory 2 | 3 | b = builder_factory('pyjs_static_ext') 4 | b.to_yaml() 5 | b.to_json() 6 | 7 | 8 | -------------------------------------------------------------------------------- /source/projects/py/tests/xlsx/jit_matrix_analysis.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/py/tests/xlsx/jit_matrix_analysis.xlsx -------------------------------------------------------------------------------- /source/projects/pyjs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/fn_python3_external.cmake) 4 | 5 | python3_external( 6 | PROJECT_NAME ${PROJECT_NAME} 7 | BUILD_VARIANT ${BUILD_VARIANT} 8 | ) 9 | 10 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 11 | -------------------------------------------------------------------------------- /source/projects/pymx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | set(C74_MIN_API_DIR ${CMAKE_SOURCE_DIR}/source/min-api) 6 | include(${C74_MIN_API_DIR}/script/min-pretarget.cmake) 7 | include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/common.cmake) 8 | 9 | 10 | python3_external( 11 | MIN_API 12 | PROJECT_NAME ${PROJECT_NAME} 13 | BUILD_VARIANT ${BUILD_VARIANT} 14 | INCLUDE_DIRS 15 | ${THIRDPARTY_DEPS}/pybind11/include 16 | LINKS_LIBS 17 | pybind11::embed 18 | ) 19 | 20 | 21 | include(${C74_MIN_API_DIR}/script/min-posttarget.cmake) 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /source/projects/pyx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_SOURCE_DIR}/source/scripts/cmake/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | INCLUDE_DIRS 8 | ${CMAKE_CURRENT_SOURCE_DIR}/maxcpp 9 | ${CMAKE_SOURCE_DIR}/source/projects/cobra 10 | INCLUDE_COMMONSYMS 11 | ) 12 | 13 | 14 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 15 | -------------------------------------------------------------------------------- /source/projects/pyx/README.md: -------------------------------------------------------------------------------- 1 | # pyx: example use of cobra with maxcpp 2 | 3 | This is a proof-of-concept of using `cobra`, the single-header c++ python3 library for Max externals with Graham Wakefield's [maxcpp](https://github.com/grrrwaaa/maxcpp) (C++ templates for Max/MSP objects) 4 | 5 | ## Usage 6 | 7 | This can be built individually with: 8 | 9 | ```sh 10 | make pyx 11 | ``` 12 | 13 | For a relocatable dynamically-linked build 14 | 15 | ```sh 16 | make pyx-shared 17 | ``` 18 | 19 | For a relocatable statically-linked build 20 | 21 | ```sh 22 | make pyx-static 23 | ``` 24 | -------------------------------------------------------------------------------- /source/projects/xpyc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `xpyc` object 2 | 3 | [0.1.0] 4 | 5 | - Added improved `anything` msg code entry interface 6 | 7 | - Proof-of-concept external to access a python interpreter via the use of xpc channels. 8 | -------------------------------------------------------------------------------- /source/projects/xpyc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | ) 8 | 9 | set(XPCSERVICES_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${${PROJECT_NAME}_EXTERN_OUTPUT_NAME}.mxo/Contents/XPCServices") 10 | 11 | add_custom_command( 12 | TARGET ${PROJECT_NAME} 13 | POST_BUILD 14 | COMMAND mkdir -p ${XPCSERVICES_DIR} 15 | COMMAND mv ${CMAKE_BINARY_DIR}/Release/PythonService.xpc ${XPCSERVICES_DIR} 16 | COMMENT "mv build xpc service bundle to external bundle" 17 | ) 18 | 19 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 20 | -------------------------------------------------------------------------------- /source/projects/xpyc/README.md: -------------------------------------------------------------------------------- 1 | # xpyc: a max external which communicates with python3 via xpc 2 | 3 | A proof-of-concept stage Max external which uses [xpc](https://developer.apple.com/documentation/xpc?language=objc), a "lightweight mechanism for basic interprocess communication", to connect to a separate python process via an xpc service. 4 | 5 | Works on MacOS only. 6 | 7 | ## Building 8 | 9 | ```sh 10 | make xpyc 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /source/projects/xpyc/services/PythonService/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XPCService 6 | 7 | ServiceType 8 | Application 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /source/projects/xpyc/services/PythonService/PythonService.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_pyservice/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = "demo" 2 | XCODEPROJ = $(PROJECT).xcodeproj 3 | HELPFILE = $(PROJECT).maxhelp 4 | TARGETS = 5 | 6 | .PHONY: all generate build clean py pyjs 7 | 8 | all: build 9 | 10 | generate: clean 11 | @xcodegen 12 | 13 | py: generate 14 | xcodebuild -project $(XCODEPROJ) -target py 15 | 16 | build: generate 17 | @for t in $(TARGETS) ; do \ 18 | xcodebuild -project $(XCODEPROJ) -target $$t ; \ 19 | done 20 | 21 | clean: 22 | @rm -rf $(XCODEPROJ) build 23 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_pyservice/project.xcconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | TARGET_NAME = PythonService 4 | VERSION = 3.13 5 | ABIFLAGS = 6 | PREFIX = /opt/homebrew/opt/python@$(VERSION)/Frameworks/Python.framework/Versions/$(VERSION) 7 | LIBS = -ldl 8 | 9 | // -------------------------------------------------------------------------------- 10 | 11 | PY_HEADERS = $(PREFIX)/include/python$(VERSION)$(ABIFLAGS) $(NUMPY_HEADERS) 12 | PY_LIBS = $(PREFIX)/lib 13 | PY_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) 14 | 15 | PROJECT_HEADERS = $(PY_HEADERS) 16 | PROJECT_LIBS = $(PY_LIBS) 17 | PROJECT_LDFLAGS = $(LIBS) -lpython$(VERSION)$(ABIFLAGS) 18 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_pyservice/project.yml: -------------------------------------------------------------------------------- 1 | name: PythonService 2 | options: 3 | bundleIdPrefix: xpyc 4 | settings: 5 | ARCHS: $(NATIVE_ARCH) 6 | MACOSX_DEPLOYMENT_TARGET: "10.13" 7 | CODE_SIGN_IDENTITY: "-" 8 | DEVELOPMENT_TEAM: "" 9 | GCC_OPTIMIZATION_LEVEL: 0 10 | GCC_NO_COMMON_BLOCKS: No 11 | HEADER_SEARCH_PATHS: 12 | - $(PROJECT_HEADERS) 13 | INFOPLIST_FILE: $(SRCROOT)/Info.plist 14 | LIBRARY_SEARCH_PATHS: $(PROJECT_LIBS) 15 | OTHER_LDFLAGS: 16 | - $(PROJECT_LDFLAGS) 17 | PRODUCT_NAME: $(TARGET_NAME) 18 | WRAPPER_EXTENSION: xpc 19 | configFiles: 20 | Debug: project.xcconfig 21 | Release: project.xcconfig 22 | 23 | targets: 24 | PythonService: 25 | type: bundle 26 | platform: macOS 27 | sources: 28 | - main.c 29 | dependencies: 30 | - sdk: CoreFoundation.framework 31 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_python/build.sh: -------------------------------------------------------------------------------- 1 | 2 | gcc -o test test_python.c `python3-config --cflags` `python3-config --ldflags` -lpython3.13 3 | 4 | rm -rf *.dSYM 5 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_python/test_python.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | wchar_t* python_home = NULL; 8 | PyStatus status; 9 | 10 | PyConfig config; 11 | PyConfig_InitPythonConfig(&config); 12 | config.parse_argv = 0; // Disable parsing command line arguments 13 | config.isolated = 0; // default is disabled 14 | config.home = python_home; 15 | 16 | status = Py_InitializeFromConfig(&config); 17 | if (PyStatus_Exception(status)) { 18 | PyConfig_Clear(&config); 19 | printf("could not initialize python\n"); 20 | } 21 | 22 | PyConfig_Clear(&config); 23 | 24 | PyObject* main_mod = PyImport_AddModule("__main__"); // borrowed 25 | PyObject* globals = PyModule_GetDict(main_mod); // borrowed reference 26 | PyObject* builtins = PyEval_GetBuiltins(); // borrowed 27 | PyDict_SetItemString(globals, "__builtins__", builtins); 28 | 29 | PyObject* pval = PyRun_String("1+1", Py_eval_input, globals, globals); 30 | 31 | long long_result = PyLong_AsLong(pval); 32 | 33 | printf("result: %ld\n", long_result); 34 | 35 | Py_XDECREF(pval); 36 | Py_XDECREF(globals); 37 | return Py_FinalizeEx(); 38 | } 39 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_server/build.sh: -------------------------------------------------------------------------------- 1 | PROJECT="zpy" 2 | XCODEPROJ=${PROJECT}.xcodeproj 3 | HELPFILE=${PROJECT}.maxhelp 4 | 5 | echo "building the minimal zmq python server" 6 | gcc `python3-config --cflags` -I/usr/local/include -L/usr/local/lib `python3-config --ldflags` -lpython3.9 -lzmq -o server server.c 7 | rm -rf *.dSYM 8 | 9 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/test_xpc1/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: all server clean 3 | 4 | all: server client 5 | 6 | server: 7 | @gcc -o server xpc_server.c 8 | 9 | client: 10 | @gcc -o client xpc_client.c 11 | 12 | clean: 13 | @rm -f server client 14 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/test_xpc1/xpc_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | // double x = [_xField doubleValue]; 8 | // double y = [_yField doubleValue]; 9 | double x = 0.0; 10 | double y = 0.0; 11 | printf("x = %f, y = %f\n", x, y); 12 | 13 | xpc_connection_t conn = xpc_connection_create("com.demo.XPCMultiplierService", NULL); 14 | xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); 15 | // You have to set an event handler or else xpc_connection_resume will crash. 16 | xpc_connection_set_event_handler(conn, ^(xpc_object_t object) { 17 | }); 18 | xpc_connection_resume(conn); 19 | 20 | xpc_dictionary_set_double(message, "x", x); 21 | xpc_dictionary_set_double(message, "y", y); 22 | xpc_connection_send_message_with_reply(conn, message, dispatch_get_main_queue(), ^(xpc_object_t object) { 23 | double result = xpc_dictionary_get_double(object, "result"); 24 | printf("Result is %f\n", result); 25 | // [_resultField setDoubleValue:result]; 26 | }); 27 | xpc_release(message); 28 | xpc_release(conn); 29 | } -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/test_xpc2/XPCService/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XPCService 6 | 7 | ServiceType 8 | Application 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/test_xpc2/XPCService/XPCService.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/xpc/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_DEBUG_H__ 2 | #define __XPC_DEBUG_H__ 3 | 4 | __BEGIN_DECLS 5 | 6 | /*! 7 | * @function xpc_debugger_api_misuse_info 8 | * Returns a pointer to a string describing the reason XPC aborted the calling 9 | * process. On OS X, this will be the same string present in the "Application 10 | * Specific Information" section of the crash report. 11 | * 12 | * @result 13 | * A pointer to the human-readable string describing the reason the caller was 14 | * aborted. If XPC was not responsible for the program's termination, NULL will 15 | * be returned. 16 | * 17 | * @discussion 18 | * This function is only callable from within a debugger. It is not meant to be 19 | * called by the program directly. 20 | */ 21 | XPC_DEBUGGER_EXCL 22 | const char * 23 | xpc_debugger_api_misuse_info(void); 24 | 25 | __END_DECLS 26 | 27 | #endif // __XPC_DEBUG_H__ 28 | -------------------------------------------------------------------------------- /source/projects/xpyc/tests/test_xpc/xpc/endpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_ENDPOINT_H__ 2 | #define __XPC_ENDPOINT_H__ 3 | 4 | __BEGIN_DECLS 5 | 6 | /*! 7 | * @function xpc_endpoint_create 8 | * Creates a new endpoint from a connection that is suitable for embedding into 9 | * messages. 10 | * 11 | * @param connection 12 | * Only connections obtained through calls to xpc_connection_create*() may be 13 | * given to this API. Passing any other type of connection is not supported and 14 | * will result in undefined behavior. 15 | * 16 | * @result 17 | * A new endpoint object. 18 | */ 19 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 20 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 21 | xpc_endpoint_t _Nonnull 22 | xpc_endpoint_create(xpc_connection_t _Nonnull connection); 23 | 24 | __END_DECLS 25 | 26 | #endif // __XPC_ENDPOINT_H__ 27 | -------------------------------------------------------------------------------- /source/projects/zedit/.gitignore: -------------------------------------------------------------------------------- 1 | examples 2 | node_modules 3 | package-lock.json 4 | editor.bundle.js 5 | 6 | -------------------------------------------------------------------------------- /source/projects/zedit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake) 2 | 3 | 4 | python3_external( 5 | PROJECT_NAME ${PROJECT_NAME} 6 | BUILD_VARIANT ${BUILD_VARIANT} 7 | INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../mamba 8 | ) 9 | 10 | if(APPLE AND NOT BUILD_VARIANT STREQUAL local) 11 | set(RESOURCES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${${PROJECT_NAME}_EXTERN_OUTPUT_NAME}.mxo/Contents/Resources") 12 | 13 | add_custom_command( 14 | TARGET ${PROJECT_NAME} 15 | POST_BUILD 16 | COMMAND mkdir -p ${RESOURCES} 17 | COMMAND cp -rf web/public ${RESOURCES} 18 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 19 | COMMENT "Generating public web directory" 20 | ) 21 | endif() 22 | 23 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake) 24 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/Makefile: -------------------------------------------------------------------------------- 1 | 2 | BUILD_DIR=public 3 | JS=$(BUILD_DIR)/js 4 | CFLAGS=-std=c99 -Wall 5 | 6 | all: $(JS)/editor.min.js 7 | 8 | node_modules: 9 | @npm i codemirror 10 | @npm i @codemirror/lang-python 11 | @npm i @codemirror/theme-one-dark 12 | @npm i rollup @rollup/plugin-node-resolve 13 | @npm i terser 14 | 15 | 16 | editor.mjs: node_modules 17 | @echo "OK" 18 | 19 | $(JS)/editor.min.js: $(JS)/editor.bundle.js 20 | @node_modules/terser/bin/terser $(JS)/editor.bundle.js -o $(JS)/editor.min.js -c 21 | 22 | $(JS)/editor.bundle.js: editor.mjs $(BUILD_DIR)/index.html 23 | @echo "Bundling js" 24 | @node_modules/.bin/rollup -c 25 | @npx prettier --tab-width 4 --write editor.mjs 26 | 27 | $(BUILD_DIR)/index.html: index.html 28 | @echo "copy index.html -> ./public" 29 | @cp index.html $(BUILD_DIR)/index.html 30 | 31 | index.html: 32 | @echo "index.html changes" 33 | 34 | 35 | PHONY: clean reset 36 | 37 | clean: 38 | @rm -rf build 39 | 40 | reset: clean 41 | @rm -rf node_modules package.json package-lock.json 42 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | pyjs-editor 7 | 18 | 19 | 20 |
21 |

pyjs-editor

22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zedit", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "zedit.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@codemirror/lang-python": "^6.1.2", 13 | "@codemirror/theme-one-dark": "^6.1.1", 14 | "codemirror": "^6.0.1", 15 | "@rollup/plugin-node-resolve": "^15.0.2", 16 | "rollup": "^3.20.2", 17 | "terser": "^5.16.9", 18 | "express": "^4.16.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/zedit/n4m/public/images/favicon.png -------------------------------------------------------------------------------- /source/projects/zedit/n4m/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | pyjs-editor 7 | 18 | 19 | 20 |
21 |

pyjs-editor

22 |
23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /source/projects/zedit/n4m/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import {nodeResolve} from "@rollup/plugin-node-resolve" 2 | export default { 3 | input: "./editor.mjs", 4 | output: { 5 | file: "./public/js/editor.bundle.js", 6 | format: "iife" 7 | }, 8 | plugins: [nodeResolve()] 9 | } 10 | 11 | -------------------------------------------------------------------------------- /source/projects/zedit/web/.gitignore: -------------------------------------------------------------------------------- 1 | editor.bundle.js 2 | 3 | 4 | -------------------------------------------------------------------------------- /source/projects/zedit/web/Makefile: -------------------------------------------------------------------------------- 1 | 2 | BUILD_DIR=public 3 | JS=$(BUILD_DIR)/js 4 | CFLAGS=-std=c99 -Wall 5 | 6 | all: $(JS)/editor.min.js 7 | 8 | node_modules: 9 | @npm i rollup @rollup/plugin-node-resolve 10 | @npm i rollup-plugin-import-css 11 | @npm i @rollup/plugin-commonjs 12 | @npm i terser 13 | 14 | 15 | editor.mjs: node_modules 16 | @echo "OK" 17 | 18 | $(JS)/editor.min.js: $(JS)/editor.bundle.js 19 | @node_modules/terser/bin/terser $(JS)/editor.bundle.js -o $(JS)/editor.min.js -c 20 | 21 | $(JS)/editor.bundle.js: editor.mjs $(BUILD_DIR)/index.html 22 | @echo "Bundling js" 23 | @node_modules/.bin/rollup -c 24 | @npx prettier --tab-width 4 --write editor.mjs 25 | 26 | $(BUILD_DIR)/index.html: index.html 27 | @echo "copy index.html -> ./public" 28 | @cp index.html $(BUILD_DIR)/index.html 29 | 30 | index.html: 31 | @echo "index.html changes" 32 | 33 | 34 | PHONY: clean reset 35 | 36 | clean: 37 | @rm -rf build 38 | 39 | reset: clean 40 | @rm -rf node_modules package.json package-lock.json 41 | -------------------------------------------------------------------------------- /source/projects/zedit/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@codemirror/lang-python": "^6.1.2", 4 | "@codemirror/theme-one-dark": "^6.1.1", 5 | "@rollup/plugin-commonjs": "^24.1.0", 6 | "@rollup/plugin-node-resolve": "^15.3.1", 7 | "@rollup/plugin-terser": "^0.4.1", 8 | "codemirror": "^6.0.1", 9 | "highlight.js": "^11.7.0", 10 | "jquery.terminal": "^2.35.3", 11 | "prettier": "^2.8.7", 12 | "prismjs-components-importer": "^0.2.0", 13 | "rollup": "^3.29.5", 14 | "rollup-plugin-import-css": "^3.5.8", 15 | "terser": "^5.39.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/projects/zedit/web/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/projects/zedit/web/public/images/favicon.png -------------------------------------------------------------------------------- /source/projects/zedit/web/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /source/projects/zedit/web/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import {nodeResolve} from "@rollup/plugin-node-resolve" 2 | import commonjs from '@rollup/plugin-commonjs'; 3 | import css from "rollup-plugin-import-css"; 4 | 5 | export default { 6 | input: "./editor.mjs", 7 | output: { 8 | file: "./public/js/editor.bundle.js", 9 | format: "iife" 10 | }, 11 | plugins: [ 12 | nodeResolve(), 13 | css(), 14 | commonjs(), 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /source/projects/zedit/webroot: -------------------------------------------------------------------------------- 1 | ./web/public -------------------------------------------------------------------------------- /source/projects/zpy/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `zpy` object 2 | 3 | [0.1.0] 4 | 5 | - Dropped `cmzq` in order to work directly with `zeromq`. 6 | 7 | - Created proof-of-concept external using the `czmq` library to demonstrate accessing a python interpreter via the use of zeromq channels. -------------------------------------------------------------------------------- /source/projects/zpy/README.md: -------------------------------------------------------------------------------- 1 | # zpy: python3 via zmq in max 2 | 3 | A max external which uses `zmq` to connect to a separate python process 4 | 5 | The objective is to replicate what the `py` external does but using zmq. 6 | 7 | ## Requires 8 | 9 | ```bash 10 | brew install zmq 11 | ``` 12 | 13 | ## Status 14 | 15 | - [ ] proof-of-concept 16 | 17 | ## TODO 18 | 19 | - how to launch python server automatically and close it with the patch 20 | 21 | ## Alternatives 22 | 23 | - [ ] run as subprocess and read and write from stdin and stdout via a pipe 24 | 25 | ## Research 26 | 27 | - 28 | 29 | - 30 | -------------------------------------------------------------------------------- /source/projects/zpy/tests/test_server/build.sh: -------------------------------------------------------------------------------- 1 | PROJECT="zpy" 2 | XCODEPROJ=${PROJECT}.xcodeproj 3 | HELPFILE=${PROJECT}.maxhelp 4 | 5 | echo "building the minimal zmq python server" 6 | gcc `python3-config --cflags` -I/usr/local/include -L/usr/local/lib `python3-config --ldflags` -lpython3.9 -lzmq -o server server.c 7 | rm -rf *.dSYM 8 | 9 | -------------------------------------------------------------------------------- /source/projects/zpy/zpy_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import zmq 4 | 5 | context = zmq.Context() 6 | 7 | # Socket to talk to server 8 | print("Connecting to python server...") 9 | socket = context.socket(zmq.REQ) 10 | socket.connect("tcp://localhost:5555") 11 | 12 | 13 | request_response = [ 14 | 15 | ('test float', 'float 10.2'), 16 | ('test int', 'int 2'), 17 | ('test list', 'list 10 sam 10.2 2 hello'), 18 | ('test XXX', 'test '), 19 | 20 | ('1+1', '2'), 21 | ('XXX', 'python-eval-error'), 22 | ] 23 | 24 | 25 | for request, expected_response in request_response: 26 | print(f"Sending request {request} ...") 27 | socket.send_string(request) 28 | 29 | # Get the reply. 30 | message = socket.recv() 31 | message = message.decode('utf8') 32 | check = message == expected_response 33 | print(f"Received reply {request} -> {check} [ {message} | {expected_response} ]") 34 | 35 | -------------------------------------------------------------------------------- /source/projects/ztp/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for `ztp` object 2 | 3 | [0.1.0] 4 | 5 | - Changed name of this project from `zthread` to `ztp` 6 | 7 | - Successful proof-of-concept project created to demonstrate accessing a spawned python interpreter via the use of threads and zeromq channels in order to prevent blocking. 8 | 9 | -------------------------------------------------------------------------------- /source/projects/ztp/README.md: -------------------------------------------------------------------------------- 1 | # ztp: the zeromq + threads + python Max external 2 | 3 | ```text 4 | ┌─────────────────────────────────────────────────┐ 5 | │┌───────────┐ ┌───────────┐│ 6 | ││ │ │python code││ 7 | ││ client │◀────────zeromq───────▶│ server ││ 8 | ││ │ │ (spawned) ││ 9 | │└───────────┘ └───────────┘│ 10 | │ ztp external │ 11 | └─────────────────────────────────────────────────┘ 12 | ``` 13 | 14 | The `ztp` external (the name refers to python, threads and zeromq) uses `zmq` with threading for non-blocking communication with a spawned python code interpretation server which evaluates and executes python code and sends back the result. 15 | 16 | The combination of threads, zeromq and remote process mgmt of the spawned server make this much more usable than `zpy`, an earlier effort which lacked threads and which suffered from blocking during communication with the server. 17 | 18 | ## Requires 19 | 20 | ```bash 21 | brew install zmq 22 | ``` 23 | 24 | ## Learnings 25 | 26 | - This works: one thread per zmq socket as per the zmq rules. 27 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/process/hello.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from random import randint 4 | 5 | with open('/tmp/out.txt', 'w') as f: 6 | n = str(randint(0,100)) 7 | f.write(f"{n}\n") 8 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/process/hello.sh: -------------------------------------------------------------------------------- 1 | echo "HELO WORLD" 2 | 3 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/process/test_spawn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | extern char **environ; 10 | 11 | void run_cmd(char *cmd) 12 | { 13 | pid_t pid; 14 | char *argv[] = {"python3", cmd, NULL}; 15 | int status; 16 | printf("Run command: %s\n", cmd); 17 | status = posix_spawn(&pid, "/opt/homebrew/bin/python3", NULL, NULL, argv, environ); 18 | if (status == 0) { 19 | printf("Child pid: %i\n", pid); 20 | do { 21 | if (waitpid(pid, &status, 0) != -1) { 22 | printf("Child status %d\n", WEXITSTATUS(status)); 23 | } else { 24 | perror("waitpid"); 25 | exit(1); 26 | } 27 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 28 | } else { 29 | printf("posix_spawn: %s\n", strerror(status)); 30 | } 31 | } 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | run_cmd(argv[1]); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/process/test_spawn2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | extern char **environ; 10 | 11 | void run_cmd(char *cmd) 12 | { 13 | pid_t pid; 14 | char *argv[] = {"sh", "-c", cmd, NULL}; 15 | int status; 16 | printf("Run command: %s\n", cmd); 17 | status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); 18 | if (status == 0) { 19 | printf("Child pid: %i\n", pid); 20 | do { 21 | if (waitpid(pid, &status, 0) != -1) { 22 | printf("Child status %d\n", WEXITSTATUS(status)); 23 | } else { 24 | perror("waitpid"); 25 | exit(1); 26 | } 27 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 28 | } else { 29 | printf("posix_spawn: %s\n", strerror(status)); 30 | } 31 | } 32 | 33 | int main(int argc, char* argv[]) 34 | { 35 | run_cmd(argv[1]); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/threading/build.sh: -------------------------------------------------------------------------------- 1 | 2 | # brew install zeromq 3 | for i in 1 2 3 4 4 | do 5 | gcc -o test_thread${i} -lpthread test_thread${i}.c 6 | done 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/threading/test_thread1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Global variable: 6 | int i = 2; 7 | 8 | void* foo(void* p) 9 | { 10 | // Print value received as argument: 11 | printf("Value received as argument in starting routine: "); 12 | printf("%i\n", *(int*)p); 13 | 14 | // Return reference to global variable: 15 | pthread_exit(&i); 16 | } 17 | 18 | int main(void) 19 | { 20 | // Declare variable for thread's ID: 21 | pthread_t id; 22 | 23 | int j = 150; 24 | pthread_create(&id, NULL, foo, &j); 25 | 26 | int* ptr; 27 | 28 | // Wait for foo() and retrieve value in ptr; 29 | pthread_join(id, (void**)&ptr); 30 | printf("Value received by parent from child: "); 31 | printf("%i\n", *ptr); 32 | } -------------------------------------------------------------------------------- /source/projects/ztp/tests/threading/test_thread2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include //Header file for sleep(). man 3 sleep for details. 4 | #include 5 | 6 | // A normal C function that is executed as a thread 7 | // when its name is specified in pthread_create() 8 | void *myThreadFun(void *vargp) 9 | { 10 | sleep(1); 11 | printf("Printing GeeksQuiz from Thread \n"); 12 | return NULL; 13 | } 14 | 15 | int main() 16 | { 17 | pthread_t thread_id; 18 | printf("Before Thread\n"); 19 | pthread_create(&thread_id, NULL, myThreadFun, NULL); 20 | pthread_join(thread_id, NULL); 21 | printf("After Thread\n"); 22 | exit(0); 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /source/projects/ztp/tests/threading/test_thread3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // Let us create a global variable to change it in threads 7 | int g = 0; 8 | 9 | // The function to be executed by all threads 10 | void *myThreadFun(void *vargp) 11 | { 12 | // Store the value argument passed to this thread 13 | int *myid = (int *)vargp; 14 | 15 | // Let us create a static variable to observe its changes 16 | static int s = 0; 17 | 18 | // Change static and global variables 19 | ++s; ++g; 20 | 21 | // Print the argument, static and global variables 22 | printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g); 23 | } 24 | 25 | int main() 26 | { 27 | int i; 28 | pthread_t tid; 29 | 30 | // Let us create three threads 31 | for (i = 0; i < 3; i++) 32 | pthread_create(&tid, NULL, myThreadFun, (void *)&tid); 33 | 34 | pthread_exit(NULL); 35 | return 0; 36 | } 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /source/scripts/cmake/common.cmake: -------------------------------------------------------------------------------- 1 | # this overrides the 10.11 OSX_DEPLOYMENT_TARGET set by max-sdk 2 | unset(CMAKE_OSX_DEPLOYMENT_TARGET) 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "requires >= 10.15" FORCE) 4 | set(CMAKE_EXPORT_COMPILE_COMMANDS True) 5 | -------------------------------------------------------------------------------- /source/scripts/install_leo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # install Leo 6.7.7, main branch, build 9761e97ee3 4 | 5 | virtualenv .venv 6 | source .venv/bin/activate 7 | pip install leo==6.7.7 8 | -------------------------------------------------------------------------------- /source/thirdparty/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | if(pymx IN_LIST BUILD_TARGETS) 3 | add_subdirectory(pybind11) 4 | endif() 5 | 6 | if(pktpy2 IN_LIST BUILD_TARGETS OR pktpy11 IN_LIST BUILD_TARGETS) 7 | add_subdirectory(pocketpy) 8 | endif() 9 | -------------------------------------------------------------------------------- /source/thirdparty/README.md: -------------------------------------------------------------------------------- 1 | # thirdparty folder 2 | 3 | This folder serves as a place for thirdparty dependencies which are used by more than one external. 4 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/include/pybind11/common.h: -------------------------------------------------------------------------------- 1 | #include "detail/common.h" 2 | #warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." 3 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/include/pybind11/conduit/README.txt: -------------------------------------------------------------------------------- 1 | NOTE 2 | ---- 3 | 4 | The C++ code here 5 | 6 | ** only depends on ** 7 | 8 | and nothing else. 9 | 10 | DO NOT ADD CODE WITH OTHER EXTERNAL DEPENDENCIES TO THIS DIRECTORY. 11 | 12 | Read on: 13 | 14 | pybind11_conduit_v1.h — Type-safe interoperability between different 15 | independent Python/C++ bindings systems. 16 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/include/pybind11/detail/using_smart_holder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 The Pybind Development Team. 2 | // All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | #include "struct_smart_holder.h" 9 | 10 | #include 11 | 12 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 13 | 14 | using pybind11::memory::smart_holder; 15 | 16 | PYBIND11_NAMESPACE_BEGIN(detail) 17 | 18 | template 19 | using is_smart_holder = std::is_same; 20 | 21 | PYBIND11_NAMESPACE_END(detail) 22 | PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) 23 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/include/pybind11/eigen.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "eigen/matrix.h" 13 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/include/pybind11/eigen/common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 The pybind Community. 2 | 3 | #pragma once 4 | 5 | // Common message for `static_assert()`s, which are useful to easily 6 | // preempt much less obvious errors. 7 | #define PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED \ 8 | "Pointer types (in particular `PyObject *`) are not supported as scalar types for Eigen " \ 9 | "types." 10 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/pybind11/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import sys 4 | 5 | if sys.version_info < (3, 8): # noqa: UP036 6 | msg = "pybind11 does not support Python < 3.8. v2.13 was the last release supporting Python 3.7." 7 | raise ImportError(msg) 8 | 9 | 10 | from ._version import __version__, version_info 11 | from .commands import get_cmake_dir, get_include, get_pkgconfig_dir 12 | 13 | __all__ = ( 14 | "version_info", 15 | "__version__", 16 | "get_include", 17 | "get_cmake_dir", 18 | "get_pkgconfig_dir", 19 | ) 20 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/pybind11/_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def _to_int(s: str) -> int | str: 5 | try: 6 | return int(s) 7 | except ValueError: 8 | return s 9 | 10 | 11 | __version__ = "3.0.0.dev1" 12 | version_info = tuple(_to_int(s) for s in __version__.split(".")) 13 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/pybind11/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/source/thirdparty/pybind11/pybind11/py.typed -------------------------------------------------------------------------------- /source/thirdparty/pybind11/tools/JoinPaths.cmake: -------------------------------------------------------------------------------- 1 | # This module provides function for joining paths 2 | # known from most languages 3 | # 4 | # SPDX-License-Identifier: (MIT OR CC0-1.0) 5 | # Copyright 2020 Jan Tojnar 6 | # https://github.com/jtojnar/cmake-snips 7 | # 8 | # Modelled after Python’s os.path.join 9 | # https://docs.python.org/3.7/library/os.path.html#os.path.join 10 | # Windows not supported 11 | function(join_paths joined_path first_path_segment) 12 | set(temp_path "${first_path_segment}") 13 | foreach(current_segment IN LISTS ARGN) 14 | if(NOT ("${current_segment}" STREQUAL "")) 15 | if(IS_ABSOLUTE "${current_segment}") 16 | set(temp_path "${current_segment}") 17 | else() 18 | set(temp_path "${temp_path}/${current_segment}") 19 | endif() 20 | endif() 21 | endforeach() 22 | set(${joined_path} "${temp_path}" PARENT_SCOPE) 23 | endfunction() 24 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/tools/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake 2 | 3 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 4 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 5 | endif() 6 | 7 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 8 | string(REGEX REPLACE "\n" ";" files "${files}") 9 | foreach(file ${files}) 10 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 11 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 12 | exec_program( 13 | "@CMAKE_COMMAND@" ARGS 14 | "-E remove \"$ENV{DESTDIR}${file}\"" 15 | OUTPUT_VARIABLE rm_out 16 | RETURN_VALUE rm_retval) 17 | if(NOT "${rm_retval}" STREQUAL 0) 18 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 19 | endif() 20 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 22 | endif() 23 | endforeach() 24 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/tools/pybind11.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix_for_pc_file@ 2 | includedir=@includedir_for_pc_file@ 3 | 4 | Name: @PROJECT_NAME@ 5 | Description: Seamless operability between C++11 and Python 6 | Version: @PROJECT_VERSION@ 7 | Cflags: -I${includedir} 8 | -------------------------------------------------------------------------------- /source/thirdparty/pybind11/tools/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /support/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shakfu/py-js/b7bd7a4f69c64b6dc44b4366848c2f74669f3507/support/.keep --------------------------------------------------------------------------------