openscad-cpp-evaluator 1.22.0__tar.gz → 1.23.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/PKG-INFO +1 -1
  2. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +8 -3
  3. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/CMakeLists.txt +10 -1
  4. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/api.cpp +118 -28
  5. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +86 -0
  6. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/pyproject.toml +1 -1
  7. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/.github/workflows/ci.yml +0 -0
  8. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/.github/workflows/wheels.yml +0 -0
  9. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/.gitignore +0 -0
  10. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/.gitmodules +0 -0
  11. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/CLAUDE.md +0 -0
  12. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/CMakeLists.txt +0 -0
  13. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/LICENSE +0 -0
  14. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/README.md +0 -0
  15. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/bindings/CMakeLists.txt +0 -0
  16. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/bindings/ast_to_py.cpp +0 -0
  17. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/bindings/module.cpp +0 -0
  18. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/cmake/embed_font.cmake +0 -0
  19. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/examples/CMakeLists.txt +0 -0
  20. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/examples/eval_perf_benchmark.cpp +0 -0
  21. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/examples/manifold_cache_reuse.cpp +0 -0
  22. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/examples/minimal_debugger.cpp +0 -0
  23. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  24. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/.gitignore +0 -0
  25. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  26. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  27. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/README.md +0 -0
  28. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  29. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  30. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  31. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  32. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  33. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  34. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  35. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  36. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  37. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  38. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  39. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  40. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  41. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  42. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  43. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  44. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  45. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  46. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  47. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  48. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  49. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  50. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  51. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  52. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  53. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  54. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  55. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  56. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  57. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  58. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  59. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/position.cpp +0 -0
  60. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  61. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  62. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  63. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  64. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  65. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  66. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  67. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  68. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  69. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  70. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  71. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  72. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  73. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  74. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  75. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  76. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  77. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  78. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  79. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  80. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  81. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  82. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  83. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  84. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  85. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  86. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  87. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  88. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  89. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  90. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  91. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
  92. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  93. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  94. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
  95. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  96. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  97. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  98. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  99. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  100. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  101. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  102. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  103. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  104. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
  105. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/export.hpp +0 -0
  106. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  107. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  108. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
  109. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  110. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  111. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  112. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  113. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  114. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  115. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  116. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  117. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  118. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  119. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  120. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  121. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  122. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/value.hpp +0 -0
  123. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  124. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/python/openscad_cpp_evaluator/__init__.py +0 -0
  125. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/resources/fonts/LICENSE +0 -0
  126. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/resources/fonts/LiberationSans-Bold.ttf +0 -0
  127. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
  128. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/resources/fonts/LiberationSans-Italic.ttf +0 -0
  129. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  130. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/CMakeLists.txt +0 -0
  131. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/booleans.cpp +0 -0
  132. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/builtins.hpp +0 -0
  133. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/call_args.cpp +0 -0
  134. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/color.cpp +0 -0
  135. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/control.cpp +0 -0
  136. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/dxf_dim.cpp +0 -0
  137. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/extrude.cpp +0 -0
  138. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/function_builtins.cpp +0 -0
  139. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/import.cpp +0 -0
  140. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/modifiers.cpp +0 -0
  141. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/primitives_2d.cpp +0 -0
  142. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/primitives_3d.cpp +0 -0
  143. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/registry.cpp +0 -0
  144. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/roof.cpp +0 -0
  145. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/segments.cpp +0 -0
  146. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/surface.cpp +0 -0
  147. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/text.cpp +0 -0
  148. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/topology.cpp +0 -0
  149. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/builtins/transforms.cpp +0 -0
  150. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/bytecode_compiler.cpp +0 -0
  151. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/bytecode_vm.cpp +0 -0
  152. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/colored_body.cpp +0 -0
  153. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/coverage.cpp +0 -0
  154. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/csg_generate.cpp +0 -0
  155. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/csg_resolve.cpp +0 -0
  156. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/css_colors.cpp +0 -0
  157. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/debug/debug_repl.cpp +0 -0
  158. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/debug_profile.cpp +0 -0
  159. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/eval_context.cpp +0 -0
  160. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/eval_error.cpp +0 -0
  161. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/eval_use.cpp +0 -0
  162. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/export.cpp +0 -0
  163. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/expr_eval.cpp +0 -0
  164. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/format_closure.cpp +0 -0
  165. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/import/dxf_import.cpp +0 -0
  166. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/import/mesh_import.cpp +0 -0
  167. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/import/surface_load.cpp +0 -0
  168. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/import/svg_import.cpp +0 -0
  169. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/manifold_cache.cpp +0 -0
  170. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/measure_geometry.cpp +0 -0
  171. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/mesh_check.cpp +0 -0
  172. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/stmt_eval.cpp +0 -0
  173. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/text/font_match.cpp +0 -0
  174. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/text/freetype_font_provider.cpp +0 -0
  175. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/text/text_metrics.cpp +0 -0
  176. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/user_calls.cpp +0 -0
  177. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/utf8.cpp +0 -0
  178. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/value.cpp +0 -0
  179. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/src/zip_stored.cpp +0 -0
  180. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/CMakeLists.txt +0 -0
  181. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_booleans.cpp +0 -0
  182. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_bytecode_compiler.cpp +0 -0
  183. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_children_separate.cpp +0 -0
  184. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_cli.cpp +0 -0
  185. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_control_flow.cpp +0 -0
  186. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_coverage.cpp +0 -0
  187. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_csg_tree.cpp +0 -0
  188. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_debug_hooks.cpp +0 -0
  189. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_dxf_svg_import.cpp +0 -0
  190. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_eval_context.cpp +0 -0
  191. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_export.cpp +0 -0
  192. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_expr_eval.cpp +0 -0
  193. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_extrude_roof.cpp +0 -0
  194. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_feature_detection.cpp +0 -0
  195. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_function_builtins.cpp +0 -0
  196. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_helpers.hpp +0 -0
  197. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_import_export.cpp +0 -0
  198. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_include_cache.cpp +0 -0
  199. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_manifold_cache.cpp +0 -0
  200. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_mesh_check.cpp +0 -0
  201. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_multi_color_merge.cpp +0 -0
  202. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_primitives.cpp +0 -0
  203. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_profiling.cpp +0 -0
  204. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_python_bindings.py +0 -0
  205. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_render_expr.cpp +0 -0
  206. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_scope_trail.cpp +0 -0
  207. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_scoping.cpp +0 -0
  208. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_surface.cpp +0 -0
  209. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_tail_calls.cpp +0 -0
  210. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_text.cpp +0 -0
  211. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_transforms.cpp +0 -0
  212. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_unexpected_args.cpp +0 -0
  213. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_use.cpp +0 -0
  214. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_value.cpp +0 -0
  215. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_viewport_params.cpp +0 -0
  216. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tests/test_zip_stored.cpp +0 -0
  217. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tools/cli/CMakeLists.txt +0 -0
  218. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tools/cli/cli_lib.cpp +0 -0
  219. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tools/cli/cli_lib.hpp +0 -0
  220. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/tools/cli/main.cpp +0 -0
  221. {openscad_cpp_evaluator-1.22.0 → openscad_cpp_evaluator-1.23.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.22.0
3
+ Version: 1.23.1
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -136,9 +136,14 @@ struct LibraryFileResult {
136
136
  LibraryFileResult getASTFromLibraryFile(const std::string& currFile, const std::string& libFile,
137
137
  bool includeComments = false, bool processIncludes = true);
138
138
 
139
- // OpenSCAD's library search path: (1) directory of currFile, (2)
140
- // OPENSCADPATH env var (':'-separated on POSIX, ';' on Windows), (3)
141
- // platform default library dir.
139
+ // OpenSCAD's library search path, in order: (1) directory of currFile,
140
+ // (2) each OPENSCADPATH entry (':'-separated on POSIX, ';' on Windows),
141
+ // (3) the user's own libraries folder, (4) libraries shipped beside this
142
+ // binary. OPENSCADPATH ADDS to (3) and (4) rather than replacing them,
143
+ // which is what OpenSCAD's own parser_init() does.
144
+ std::vector<std::string> librarySearchDirs(const std::string& currFile);
145
+
146
+ // The first entry of librarySearchDirs() that holds `libFile`.
142
147
  std::optional<std::string> findLibraryFile(const std::string& currFile, const std::string& libFile);
143
148
 
144
149
  // A file's statements with its `include <...>` directives resolved, where
@@ -38,7 +38,16 @@ target_include_directories(openscad_cpp_parser PRIVATE
38
38
  ${CMAKE_CURRENT_SOURCE_DIR}/grammar
39
39
  ${CMAKE_CURRENT_BINARY_DIR}
40
40
  )
41
- target_link_libraries(openscad_cpp_parser PUBLIC nlohmann_json::nlohmann_json)
41
+ # CMAKE_DL_LIBS is -ldl for api.cpp's dladdr() -- empty on macOS and
42
+ # Windows, where it lives in libSystem/kernel32. A local macOS build
43
+ # therefore links fine and manylinux (glibc < 2.34, dl still a separate
44
+ # library) does not: caught only by a wheel build.
45
+ target_link_libraries(openscad_cpp_parser PUBLIC nlohmann_json::nlohmann_json ${CMAKE_DL_LIBS})
46
+ # SHGetFolderPathW, for the real My Documents rather than an assumed
47
+ # %USERPROFILE%\Documents -- see api.cpp userLibraryDir().
48
+ if(WIN32)
49
+ target_link_libraries(openscad_cpp_parser PUBLIC shell32)
50
+ endif()
42
51
  target_compile_options(openscad_cpp_parser PRIVATE
43
52
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall;-Wextra>
44
53
  )
@@ -7,6 +7,17 @@
7
7
 
8
8
  #include <cstdlib>
9
9
  #include <filesystem>
10
+ #if defined(_WIN32)
11
+ // NOMINMAX or windows.h's max()/min() macros eat std::max below -- MSVC
12
+ // caught it as "illegal token on right side of '::'", which names neither
13
+ // the macro nor the header.
14
+ #define NOMINMAX
15
+ #define WIN32_LEAN_AND_MEAN
16
+ #include <windows.h>
17
+ #include <shlobj.h>
18
+ #else
19
+ #include <dlfcn.h>
20
+ #endif
10
21
  #include <fstream>
11
22
  #include <set>
12
23
  #include <system_error>
@@ -133,6 +144,22 @@ std::vector<std::unique_ptr<ASTNode>> getASTFromString(const std::string& code,
133
144
 
134
145
  namespace {
135
146
 
147
+ // A "not found" that says where we actually looked. The old message named
148
+ // only the includer, so "searched relative to X" read as "only X was
149
+ // searched" -- which is how #503 came to be filed against a search that
150
+ // does cover the libraries folder.
151
+ std::string notFound(const char* noun, const std::string& filename, const std::string& currentFile) {
152
+ std::string msg = std::string(noun) + " '" + filename + "' not found. Searched:";
153
+ for (const auto& d : librarySearchDirs(currentFile)) {
154
+ msg += "\n " + d;
155
+ }
156
+ return msg;
157
+ }
158
+
159
+ } // namespace
160
+
161
+ namespace {
162
+
136
163
  std::string readFile(const std::string& path) {
137
164
  std::ifstream in(path, std::ios::binary);
138
165
  if (!in) {
@@ -163,8 +190,7 @@ std::vector<std::unique_ptr<ASTNode>> resolveIncludes(std::vector<std::unique_pt
163
190
  const std::string& filename = inc.filepath->val;
164
191
  auto libFile = findLibraryFile(currentFile, filename);
165
192
  if (!libFile) {
166
- throw std::runtime_error("Included file '" + filename + "' not found. Searched relative to: " +
167
- (currentFile.empty() ? "current directory" : currentFile));
193
+ throw std::runtime_error(notFound("Included file", filename, currentFile));
168
194
  }
169
195
  std::string absLib = fs::absolute(*libFile).string();
170
196
  if (visited.count(absLib) != 0) {
@@ -185,40 +211,98 @@ std::vector<std::unique_ptr<ASTNode>> resolveIncludes(std::vector<std::unique_pt
185
211
 
186
212
  } // namespace
187
213
 
188
- std::optional<std::string> findLibraryFile(const std::string& currFile, const std::string& libFile) {
189
- std::vector<fs::path> dirs;
190
- if (!currFile.empty()) {
191
- dirs.push_back(fs::absolute(currFile).parent_path());
192
- }
214
+ namespace {
193
215
 
194
- char pathsep = ':';
195
- std::string dfltPath;
196
- const char* home = std::getenv("HOME");
216
+ // The user's own libraries folder -- OpenSCAD's
217
+ // PlatformUtils::userLibraryPath(), and the one an installer or a git clone
218
+ // of BOSL2 lands in.
219
+ std::string userLibraryDir() {
197
220
  #if defined(_WIN32)
198
- pathsep = ';';
221
+ // ASK Windows where My Documents is rather than assuming
222
+ // %USERPROFILE%\Documents. OneDrive's Known Folder Move -- on by default
223
+ // on a new machine -- relocates it to %USERPROFILE%\OneDrive\Documents,
224
+ // and a library OpenSCAD itself installed then sat somewhere we never
225
+ // looked (BelfrySCAD #503). Same call and same flag OpenSCAD makes
226
+ // (PlatformUtils-win.cc getFolderPath).
227
+ wchar_t buf[MAX_PATH] = {0};
228
+ if (SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, buf) == S_OK) {
229
+ return (fs::path(buf) / "OpenSCAD" / "libraries").string();
230
+ }
199
231
  const char* userProfile = std::getenv("USERPROFILE");
200
- if (userProfile) {
201
- dfltPath = std::string(userProfile) + "\\Documents\\OpenSCAD\\libraries";
232
+ return userProfile ? (fs::path(userProfile) / "Documents" / "OpenSCAD" / "libraries").string()
233
+ : std::string();
234
+ #else
235
+ const char* home = std::getenv("HOME");
236
+ if (!home) {
237
+ return {};
202
238
  }
203
- #elif defined(__APPLE__)
204
- if (home) {
205
- dfltPath = std::string(home) + "/Documents/OpenSCAD/libraries";
239
+ #if defined(__APPLE__)
240
+ return (fs::path(home) / "Documents" / "OpenSCAD" / "libraries").string();
241
+ #else
242
+ return (fs::path(home) / ".local" / "share" / "OpenSCAD" / "libraries").string();
243
+ #endif
244
+ #endif
245
+ }
246
+
247
+ // Libraries shipped alongside this build -- OpenSCAD's
248
+ // PlatformUtils::resourcePath("libraries"). "Alongside" means beside the
249
+ // binary this code was linked into: the CLI executable, or the Python
250
+ // extension inside its installed package.
251
+ // ponytail: one candidate directory, no ../share/openscad/libraries walk --
252
+ // add the walk if a packaging layout ever puts the libraries somewhere
253
+ // other than next to the binary.
254
+ std::string bundledLibraryDir() {
255
+ fs::path self;
256
+ #if defined(_WIN32)
257
+ HMODULE mod = nullptr;
258
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
259
+ | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
260
+ reinterpret_cast<LPCWSTR>(&userLibraryDir), &mod)) {
261
+ wchar_t buf[MAX_PATH] = {0};
262
+ if (GetModuleFileNameW(mod, buf, MAX_PATH)) {
263
+ self = buf;
264
+ }
206
265
  }
207
266
  #else
208
- if (home) {
209
- dfltPath = std::string(home) + "/.local/share/OpenSCAD/libraries";
267
+ Dl_info info;
268
+ if (dladdr(reinterpret_cast<void*>(&userLibraryDir), &info) && info.dli_fname) {
269
+ self = info.dli_fname;
210
270
  }
211
271
  #endif
272
+ if (self.empty()) {
273
+ return {};
274
+ }
275
+ std::error_code ec;
276
+ return (fs::absolute(self, ec).parent_path() / "libraries").string();
277
+ }
278
+
279
+ } // namespace
212
280
 
281
+ std::vector<std::string> librarySearchDirs(const std::string& currFile) {
282
+ std::vector<std::string> dirs;
283
+ if (!currFile.empty()) {
284
+ dirs.push_back(fs::absolute(currFile).parent_path().string());
285
+ }
286
+
287
+ #if defined(_WIN32)
288
+ const char pathsep = ';';
289
+ #else
290
+ const char pathsep = ':';
291
+ #endif
292
+
293
+ // OPENSCADPATH comes FIRST and adds to the built-in paths rather than
294
+ // replacing them -- exactly what OpenSCAD's parser_init() does. It used
295
+ // to replace them, so setting the variable for one library hid every
296
+ // other, including a BOSL2 sitting in the default folder (#503).
213
297
  const char* envPath = std::getenv("OPENSCADPATH");
214
- std::string env = envPath ? std::string(envPath) : dfltPath;
215
- if (!env.empty()) {
298
+ if (envPath) {
299
+ std::string env(envPath);
216
300
  size_t start = 0;
217
301
  while (start <= env.size()) {
218
302
  size_t pos = env.find(pathsep, start);
219
303
  std::string part = (pos == std::string::npos) ? env.substr(start) : env.substr(start, pos - start);
220
304
  if (!part.empty()) {
221
- dirs.emplace_back(part);
305
+ dirs.push_back(part);
222
306
  }
223
307
  if (pos == std::string::npos) {
224
308
  break;
@@ -227,8 +311,17 @@ std::optional<std::string> findLibraryFile(const std::string& currFile, const st
227
311
  }
228
312
  }
229
313
 
230
- for (const auto& d : dirs) {
231
- fs::path candidate = d / libFile;
314
+ for (const std::string& d : {userLibraryDir(), bundledLibraryDir()}) {
315
+ if (!d.empty()) {
316
+ dirs.push_back(d);
317
+ }
318
+ }
319
+ return dirs;
320
+ }
321
+
322
+ std::optional<std::string> findLibraryFile(const std::string& currFile, const std::string& libFile) {
323
+ for (const auto& d : librarySearchDirs(currFile)) {
324
+ fs::path candidate = fs::path(d) / libFile;
232
325
  std::error_code ec;
233
326
  if (fs::is_regular_file(candidate, ec)) {
234
327
  return candidate.string();
@@ -255,9 +348,7 @@ LibraryFileResult getASTFromLibraryFile(const std::string& currFile, const std::
255
348
  bool processIncludes) {
256
349
  auto found = findLibraryFile(currFile, libFile);
257
350
  if (!found) {
258
- throw std::runtime_error("Library file '" + libFile +
259
- "' not found in search paths. Searched in: current file directory, OPENSCADPATH, and "
260
- "platform default paths.");
351
+ throw std::runtime_error(notFound("Library file", libFile, currFile));
261
352
  }
262
353
  auto ast = getASTFromFile(*found, includeComments, processIncludes);
263
354
  return LibraryFileResult{std::move(ast), *found};
@@ -346,8 +437,7 @@ void collectProgram(const FileAst& nodes, const std::string& currentFile, bool i
346
437
  const std::string& filename = inc.filepath->val;
347
438
  auto libFile = findLibraryFile(currentFile, filename);
348
439
  if (!libFile) {
349
- throw std::runtime_error("Included file '" + filename + "' not found. Searched relative to: " +
350
- (currentFile.empty() ? "current directory" : currentFile));
440
+ throw std::runtime_error(notFound("Included file", filename, currentFile));
351
441
  }
352
442
  std::string absLib = fs::absolute(*libFile).string();
353
443
  if (!visited.insert(absLib).second) continue;
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <gtest/gtest.h>
4
4
 
5
+ #include <algorithm>
6
+ #include <cstdlib>
5
7
  #include <filesystem>
6
8
  #include <fstream>
7
9
  #include <random>
@@ -138,3 +140,87 @@ TEST(FileApi, FindLibraryFileReturnsNulloptWhenMissing) {
138
140
  auto found = findLibraryFile("", "definitely_missing_file_xyz.scad");
139
141
  EXPECT_FALSE(found.has_value());
140
142
  }
143
+
144
+ namespace {
145
+
146
+ // RAII OPENSCADPATH, so one test's setting cannot leak into the next.
147
+ class ScopedOpenscadPath {
148
+ public:
149
+ explicit ScopedOpenscadPath(const std::string& value) {
150
+ const char* prev = std::getenv("OPENSCADPATH");
151
+ had_ = prev != nullptr;
152
+ if (had_) prev_ = prev;
153
+ set(value.c_str());
154
+ }
155
+ ~ScopedOpenscadPath() {
156
+ if (had_) {
157
+ set(prev_.c_str());
158
+ } else {
159
+ #if defined(_WIN32)
160
+ _putenv_s("OPENSCADPATH", "");
161
+ #else
162
+ unsetenv("OPENSCADPATH");
163
+ #endif
164
+ }
165
+ }
166
+ private:
167
+ static void set(const char* v) {
168
+ #if defined(_WIN32)
169
+ _putenv_s("OPENSCADPATH", v);
170
+ #else
171
+ setenv("OPENSCADPATH", v, 1);
172
+ #endif
173
+ }
174
+ bool had_ = false;
175
+ std::string prev_;
176
+ };
177
+
178
+ } // namespace
179
+
180
+ TEST(FileApi, OpenscadPathAddsToTheBuiltInDirsRatherThanReplacingThem) {
181
+ // BelfrySCAD #503: `env = envPath ? envPath : dfltPath` meant setting
182
+ // OPENSCADPATH for one library hid every library in the default folder.
183
+ std::vector<std::string> without = librarySearchDirs("");
184
+ TempDir dir;
185
+ ScopedOpenscadPath scoped(dir.path().string());
186
+ std::vector<std::string> with = librarySearchDirs("");
187
+
188
+ EXPECT_EQ(with.size(), without.size() + 1);
189
+ EXPECT_EQ(with.front(), dir.path().string()); // and it is searched FIRST
190
+ for (const auto& d : without) {
191
+ EXPECT_NE(std::find(with.begin(), with.end(), d), with.end()) << d;
192
+ }
193
+ }
194
+
195
+ TEST(FileApi, FindLibraryFileSearchesOpenscadPath) {
196
+ TempDir libs;
197
+ fs::create_directories(libs.path() / "MYLIB");
198
+ fs::path libFile = libs.path() / "MYLIB" / "std.scad";
199
+ writeFile(libFile, "x = 1;\n");
200
+
201
+ TempDir docs;
202
+ fs::path mainFile = docs.path() / "main.scad";
203
+ writeFile(mainFile, "x = 1;\n");
204
+
205
+ ScopedOpenscadPath scoped(libs.path().string());
206
+ auto found = findLibraryFile(mainFile.string(), "MYLIB/std.scad");
207
+ ASSERT_TRUE(found.has_value());
208
+ EXPECT_EQ(fs::path(*found), libFile);
209
+ }
210
+
211
+ TEST(FileApi, MissingIncludeErrorNamesEveryDirectorySearched) {
212
+ TempDir dir;
213
+ fs::path mainFile = dir.path() / "main.scad";
214
+ writeFile(mainFile, "include <NOPE/std.scad>\n");
215
+
216
+ try {
217
+ getASTFromFile(mainFile.string());
218
+ FAIL() << "expected a missing-include error";
219
+ } catch (const std::runtime_error& e) {
220
+ std::string msg = e.what();
221
+ EXPECT_NE(msg.find("NOPE/std.scad"), std::string::npos) << msg;
222
+ for (const auto& d : librarySearchDirs(mainFile.string())) {
223
+ EXPECT_NE(msg.find(d), std::string::npos) << msg;
224
+ }
225
+ }
226
+ }
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "1.22.0"
7
+ version = "1.23.1"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"