IncludeCPP 3.4.0__tar.gz → 3.4.5__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.
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/PKG-INFO +21 -2
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/SOURCES.txt +20 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/PKG-INFO +21 -2
- {includecpp-3.4.0 → includecpp-3.4.5}/README.md +20 -1
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/__init__.py +59 -58
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/cli/commands.py +380 -1
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/cppy_converter.py +101 -18
- includecpp-3.4.5/includecpp/core/cssl/__init__.py +40 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_builtins.py +1693 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_events.py +621 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_modules.py +2803 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_parser.py +1778 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_runtime.py +1560 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_syntax.py +488 -0
- includecpp-3.4.5/includecpp/core/cssl/cssl_types.py +390 -0
- includecpp-3.4.5/includecpp/core/cssl_bridge.py +204 -0
- includecpp-3.4.5/includecpp/core/cssl_bridge.pyi +149 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/generator/parser.cpp +41 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/pyproject.toml +63 -60
- {includecpp-3.4.0 → includecpp-3.4.5}/setup.py +1 -1
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/dependency_links.txt +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/entry_points.txt +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/requires.txt +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/IncludeCPP.egg-info/top_level.txt +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/LICENSE +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/MANIFEST.in +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/__init__.pyi +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/__main__.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/cli/__init__.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/cli/config_parser.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/__init__.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/ai_integration.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/build_manager.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/cpp_api.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/cpp_api.pyi +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/error_catalog.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/error_formatter.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/exceptions.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/path_discovery.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/project_ui.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/core/settings_ui.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/generator/__init__.py +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/generator/parser.h +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/generator/type_resolver.cpp +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/generator/type_resolver.h +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/py.typed +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/includecpp/templates/cpp.proj.template +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/requirements.txt +0 -0
- {includecpp-3.4.0 → includecpp-3.4.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IncludeCPP
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.5
|
|
4
4
|
Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
|
|
5
5
|
Home-page: https://github.com/liliassg/IncludeCPP
|
|
6
6
|
Author: Lilias Hatterscheidt
|
|
@@ -625,6 +625,25 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
625
625
|
|
|
626
626
|
# Changelog
|
|
627
627
|
|
|
628
|
+
## v3.4.2
|
|
629
|
+
- **New Feature: `exec` Command**
|
|
630
|
+
- Interactive REPL for quick code testing without creating files
|
|
631
|
+
- `includecpp exec py` - Python REPL with IncludeCPP support
|
|
632
|
+
- `includecpp exec cpp` - C++ REPL with auto-compilation
|
|
633
|
+
- Auto-import modules: `includecpp exec py mymodule`
|
|
634
|
+
- Auto-import from plugins: `includecpp exec py plugins/math.cp`
|
|
635
|
+
- Import all modules: `includecpp exec py --all`
|
|
636
|
+
- Enter code line by line, press ENTER on empty line to execute
|
|
637
|
+
|
|
638
|
+
## v3.4.1
|
|
639
|
+
- **Bug Fixes:**
|
|
640
|
+
- fix command: Fixed false positives for unused variables (sum, memory_) using word-boundary matching
|
|
641
|
+
- CPPY: C++ reserved words (double, int, void, etc.) now properly escaped as Python identifiers
|
|
642
|
+
- CPPY: C++ STL functions (accumulate, find, sort, reverse) properly converted to Python equivalents
|
|
643
|
+
- CPPY: Member variables with trailing underscore (memory_) now get self. prefix
|
|
644
|
+
- CPPY: Private class members now detected for self. prefix conversion
|
|
645
|
+
- Plugin: Auto-detect header files from #include directives in source files
|
|
646
|
+
|
|
628
647
|
## v3.4.0
|
|
629
648
|
- **CodeMaker Major Update:**
|
|
630
649
|
- New Source node type with 8 connection ports for code generation
|
|
@@ -787,4 +806,4 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
787
806
|
|
|
788
807
|
---
|
|
789
808
|
|
|
790
|
-
MIT License | v3.4.
|
|
809
|
+
MIT License | v3.4.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -17,12 +17,22 @@ setup.py
|
|
|
17
17
|
./includecpp/core/cpp_api.py
|
|
18
18
|
./includecpp/core/cpp_api.pyi
|
|
19
19
|
./includecpp/core/cppy_converter.py
|
|
20
|
+
./includecpp/core/cssl_bridge.py
|
|
21
|
+
./includecpp/core/cssl_bridge.pyi
|
|
20
22
|
./includecpp/core/error_catalog.py
|
|
21
23
|
./includecpp/core/error_formatter.py
|
|
22
24
|
./includecpp/core/exceptions.py
|
|
23
25
|
./includecpp/core/path_discovery.py
|
|
24
26
|
./includecpp/core/project_ui.py
|
|
25
27
|
./includecpp/core/settings_ui.py
|
|
28
|
+
./includecpp/core/cssl/__init__.py
|
|
29
|
+
./includecpp/core/cssl/cssl_builtins.py
|
|
30
|
+
./includecpp/core/cssl/cssl_events.py
|
|
31
|
+
./includecpp/core/cssl/cssl_modules.py
|
|
32
|
+
./includecpp/core/cssl/cssl_parser.py
|
|
33
|
+
./includecpp/core/cssl/cssl_runtime.py
|
|
34
|
+
./includecpp/core/cssl/cssl_syntax.py
|
|
35
|
+
./includecpp/core/cssl/cssl_types.py
|
|
26
36
|
./includecpp/generator/__init__.py
|
|
27
37
|
./includecpp/generator/parser.cpp
|
|
28
38
|
./includecpp/generator/parser.h
|
|
@@ -48,12 +58,22 @@ includecpp/core/build_manager.py
|
|
|
48
58
|
includecpp/core/cpp_api.py
|
|
49
59
|
includecpp/core/cpp_api.pyi
|
|
50
60
|
includecpp/core/cppy_converter.py
|
|
61
|
+
includecpp/core/cssl_bridge.py
|
|
62
|
+
includecpp/core/cssl_bridge.pyi
|
|
51
63
|
includecpp/core/error_catalog.py
|
|
52
64
|
includecpp/core/error_formatter.py
|
|
53
65
|
includecpp/core/exceptions.py
|
|
54
66
|
includecpp/core/path_discovery.py
|
|
55
67
|
includecpp/core/project_ui.py
|
|
56
68
|
includecpp/core/settings_ui.py
|
|
69
|
+
includecpp/core/cssl/__init__.py
|
|
70
|
+
includecpp/core/cssl/cssl_builtins.py
|
|
71
|
+
includecpp/core/cssl/cssl_events.py
|
|
72
|
+
includecpp/core/cssl/cssl_modules.py
|
|
73
|
+
includecpp/core/cssl/cssl_parser.py
|
|
74
|
+
includecpp/core/cssl/cssl_runtime.py
|
|
75
|
+
includecpp/core/cssl/cssl_syntax.py
|
|
76
|
+
includecpp/core/cssl/cssl_types.py
|
|
57
77
|
includecpp/generator/__init__.py
|
|
58
78
|
includecpp/generator/parser.cpp
|
|
59
79
|
includecpp/generator/parser.h
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IncludeCPP
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.5
|
|
4
4
|
Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
|
|
5
5
|
Home-page: https://github.com/liliassg/IncludeCPP
|
|
6
6
|
Author: Lilias Hatterscheidt
|
|
@@ -625,6 +625,25 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
625
625
|
|
|
626
626
|
# Changelog
|
|
627
627
|
|
|
628
|
+
## v3.4.2
|
|
629
|
+
- **New Feature: `exec` Command**
|
|
630
|
+
- Interactive REPL for quick code testing without creating files
|
|
631
|
+
- `includecpp exec py` - Python REPL with IncludeCPP support
|
|
632
|
+
- `includecpp exec cpp` - C++ REPL with auto-compilation
|
|
633
|
+
- Auto-import modules: `includecpp exec py mymodule`
|
|
634
|
+
- Auto-import from plugins: `includecpp exec py plugins/math.cp`
|
|
635
|
+
- Import all modules: `includecpp exec py --all`
|
|
636
|
+
- Enter code line by line, press ENTER on empty line to execute
|
|
637
|
+
|
|
638
|
+
## v3.4.1
|
|
639
|
+
- **Bug Fixes:**
|
|
640
|
+
- fix command: Fixed false positives for unused variables (sum, memory_) using word-boundary matching
|
|
641
|
+
- CPPY: C++ reserved words (double, int, void, etc.) now properly escaped as Python identifiers
|
|
642
|
+
- CPPY: C++ STL functions (accumulate, find, sort, reverse) properly converted to Python equivalents
|
|
643
|
+
- CPPY: Member variables with trailing underscore (memory_) now get self. prefix
|
|
644
|
+
- CPPY: Private class members now detected for self. prefix conversion
|
|
645
|
+
- Plugin: Auto-detect header files from #include directives in source files
|
|
646
|
+
|
|
628
647
|
## v3.4.0
|
|
629
648
|
- **CodeMaker Major Update:**
|
|
630
649
|
- New Source node type with 8 connection ports for code generation
|
|
@@ -787,4 +806,4 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
787
806
|
|
|
788
807
|
---
|
|
789
808
|
|
|
790
|
-
MIT License | v3.4.
|
|
809
|
+
MIT License | v3.4.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -591,6 +591,25 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
591
591
|
|
|
592
592
|
# Changelog
|
|
593
593
|
|
|
594
|
+
## v3.4.2
|
|
595
|
+
- **New Feature: `exec` Command**
|
|
596
|
+
- Interactive REPL for quick code testing without creating files
|
|
597
|
+
- `includecpp exec py` - Python REPL with IncludeCPP support
|
|
598
|
+
- `includecpp exec cpp` - C++ REPL with auto-compilation
|
|
599
|
+
- Auto-import modules: `includecpp exec py mymodule`
|
|
600
|
+
- Auto-import from plugins: `includecpp exec py plugins/math.cp`
|
|
601
|
+
- Import all modules: `includecpp exec py --all`
|
|
602
|
+
- Enter code line by line, press ENTER on empty line to execute
|
|
603
|
+
|
|
604
|
+
## v3.4.1
|
|
605
|
+
- **Bug Fixes:**
|
|
606
|
+
- fix command: Fixed false positives for unused variables (sum, memory_) using word-boundary matching
|
|
607
|
+
- CPPY: C++ reserved words (double, int, void, etc.) now properly escaped as Python identifiers
|
|
608
|
+
- CPPY: C++ STL functions (accumulate, find, sort, reverse) properly converted to Python equivalents
|
|
609
|
+
- CPPY: Member variables with trailing underscore (memory_) now get self. prefix
|
|
610
|
+
- CPPY: Private class members now detected for self. prefix conversion
|
|
611
|
+
- Plugin: Auto-detect header files from #include directives in source files
|
|
612
|
+
|
|
594
613
|
## v3.4.0
|
|
595
614
|
- **CodeMaker Major Update:**
|
|
596
615
|
- New Source node type with 8 connection ports for code generation
|
|
@@ -753,4 +772,4 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
753
772
|
|
|
754
773
|
---
|
|
755
774
|
|
|
756
|
-
MIT License | v3.4.
|
|
775
|
+
MIT License | v3.4.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -1,58 +1,59 @@
|
|
|
1
|
-
from .core.cpp_api import CppApi
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
f"
|
|
37
|
-
f"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
f"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
1
|
+
from .core.cpp_api import CppApi
|
|
2
|
+
from .core import cssl_bridge as CSSL
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
__version__ = "3.4.5"
|
|
6
|
+
__all__ = ["CppApi", "CSSL"]
|
|
7
|
+
|
|
8
|
+
# Module-level cache for C++ modules
|
|
9
|
+
_api_instance = None
|
|
10
|
+
_loaded_modules = {}
|
|
11
|
+
|
|
12
|
+
def _get_api():
|
|
13
|
+
"""Get or create singleton CppApi instance."""
|
|
14
|
+
global _api_instance
|
|
15
|
+
if _api_instance is None:
|
|
16
|
+
_api_instance = CppApi()
|
|
17
|
+
return _api_instance
|
|
18
|
+
|
|
19
|
+
def __getattr__(name: str):
|
|
20
|
+
"""Enable: from includecpp import fast_list
|
|
21
|
+
|
|
22
|
+
This hook is called when Python cannot find an attribute in this module.
|
|
23
|
+
It allows dynamic C++ module loading via the import system.
|
|
24
|
+
"""
|
|
25
|
+
if name.startswith('_'):
|
|
26
|
+
raise AttributeError(f"module 'includecpp' has no attribute '{name}'")
|
|
27
|
+
|
|
28
|
+
if name in _loaded_modules:
|
|
29
|
+
return _loaded_modules[name]
|
|
30
|
+
|
|
31
|
+
api = _get_api()
|
|
32
|
+
|
|
33
|
+
if name not in api.registry:
|
|
34
|
+
available = list(api.registry.keys())
|
|
35
|
+
raise AttributeError(
|
|
36
|
+
f"Module '{name}' not found. "
|
|
37
|
+
f"Available: {available}. "
|
|
38
|
+
f"Run 'includecpp rebuild' first."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if api.need_update(name):
|
|
42
|
+
warnings.warn(
|
|
43
|
+
f"Module '{name}' source files changed. "
|
|
44
|
+
f"Run 'includecpp rebuild' to update.",
|
|
45
|
+
UserWarning
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
module = api.include(name)
|
|
49
|
+
_loaded_modules[name] = module
|
|
50
|
+
return module
|
|
51
|
+
|
|
52
|
+
def __dir__():
|
|
53
|
+
"""List available attributes including C++ modules."""
|
|
54
|
+
base = ['CppApi', 'CSSL', '__version__']
|
|
55
|
+
try:
|
|
56
|
+
api = _get_api()
|
|
57
|
+
return sorted(set(base + list(api.registry.keys())))
|
|
58
|
+
except Exception:
|
|
59
|
+
return base
|
|
@@ -4436,8 +4436,10 @@ def fix(module_name, all_modules, exclude, undo, auto_fix, verbose, use_ai):
|
|
|
4436
4436
|
if var_decl:
|
|
4437
4437
|
var_name = var_decl.group(1)
|
|
4438
4438
|
# Check if variable appears again in rest of content
|
|
4439
|
+
# v3.4.1: Use word boundaries to avoid false positives from substring matches
|
|
4439
4440
|
rest_content = '\n'.join(lines[i:])
|
|
4440
|
-
|
|
4441
|
+
uses = len(re.findall(rf'\b{re.escape(var_name)}\b', rest_content))
|
|
4442
|
+
if uses <= 1:
|
|
4441
4443
|
add_issue('info', 'Mistake', file_path, i, 'C003',
|
|
4442
4444
|
f"Variable '{var_name}' may be unused",
|
|
4443
4445
|
"Remove unused variable or mark as [[maybe_unused]]")
|
|
@@ -7133,6 +7135,383 @@ def cppy_types():
|
|
|
7133
7135
|
click.echo("=" * 60)
|
|
7134
7136
|
|
|
7135
7137
|
|
|
7138
|
+
# ============================================================================
|
|
7139
|
+
# EXEC - Interactive Code Execution
|
|
7140
|
+
# ============================================================================
|
|
7141
|
+
|
|
7142
|
+
@cli.command()
|
|
7143
|
+
@click.argument('lang', type=click.Choice(['py', 'cpp', 'python', 'c++']))
|
|
7144
|
+
@click.argument('path', required=False, type=click.Path())
|
|
7145
|
+
@click.option('--all', 'import_all', is_flag=True, help='Import all available modules')
|
|
7146
|
+
def exec(lang, path, import_all):
|
|
7147
|
+
"""Execute code interactively for quick testing.
|
|
7148
|
+
|
|
7149
|
+
Run Python or C++ code snippets without creating files.
|
|
7150
|
+
Perfect for testing your IncludeCPP modules quickly.
|
|
7151
|
+
|
|
7152
|
+
\b
|
|
7153
|
+
Usage:
|
|
7154
|
+
includecpp exec py # Interactive Python
|
|
7155
|
+
includecpp exec cpp # Interactive C++
|
|
7156
|
+
includecpp exec py mymodule # Auto-import mymodule
|
|
7157
|
+
includecpp exec py plugins/x.cp # Auto-import from plugin
|
|
7158
|
+
includecpp exec py --all # Import all modules
|
|
7159
|
+
|
|
7160
|
+
\b
|
|
7161
|
+
Controls:
|
|
7162
|
+
ENTER = Add new line
|
|
7163
|
+
Empty line = Execute code (press ENTER twice)
|
|
7164
|
+
CTRL+C = Cancel
|
|
7165
|
+
|
|
7166
|
+
\b
|
|
7167
|
+
Examples:
|
|
7168
|
+
$ includecpp exec py fast_math
|
|
7169
|
+
>>> x = fast_math.add(1, 2)
|
|
7170
|
+
>>> print(x)
|
|
7171
|
+
>>>
|
|
7172
|
+
3
|
|
7173
|
+
"""
|
|
7174
|
+
import sys
|
|
7175
|
+
import subprocess
|
|
7176
|
+
import tempfile
|
|
7177
|
+
from pathlib import Path as PathLib
|
|
7178
|
+
|
|
7179
|
+
# Normalize language
|
|
7180
|
+
is_python = lang in ('py', 'python')
|
|
7181
|
+
lang_name = 'Python' if is_python else 'C++'
|
|
7182
|
+
|
|
7183
|
+
# Build imports/includes
|
|
7184
|
+
imports = []
|
|
7185
|
+
includes = []
|
|
7186
|
+
|
|
7187
|
+
if import_all:
|
|
7188
|
+
# Import all available modules
|
|
7189
|
+
try:
|
|
7190
|
+
from ..core.cpp_api import CppApi
|
|
7191
|
+
api = CppApi()
|
|
7192
|
+
modules = list(api.registry.keys())
|
|
7193
|
+
if is_python:
|
|
7194
|
+
for mod in modules:
|
|
7195
|
+
imports.append(f'from includecpp import {mod}')
|
|
7196
|
+
if modules:
|
|
7197
|
+
click.secho(f"Auto-importing {len(modules)} modules: {', '.join(modules)}", fg='cyan')
|
|
7198
|
+
else:
|
|
7199
|
+
for mod in modules:
|
|
7200
|
+
includes.append(f'#include "{mod}.h"')
|
|
7201
|
+
if modules:
|
|
7202
|
+
click.secho(f"Auto-including {len(modules)} headers", fg='cyan')
|
|
7203
|
+
except Exception:
|
|
7204
|
+
click.secho("Warning: Could not load module registry", fg='yellow')
|
|
7205
|
+
|
|
7206
|
+
elif path:
|
|
7207
|
+
path_obj = PathLib(path)
|
|
7208
|
+
module_name = None
|
|
7209
|
+
|
|
7210
|
+
# Check if it's a .cp plugin file
|
|
7211
|
+
if path.endswith('.cp') or '/plugins/' in path or '\\plugins\\' in path:
|
|
7212
|
+
# Extract module name from plugin path
|
|
7213
|
+
module_name = path_obj.stem
|
|
7214
|
+
elif path_obj.exists():
|
|
7215
|
+
# It's a file path
|
|
7216
|
+
module_name = path_obj.stem
|
|
7217
|
+
else:
|
|
7218
|
+
# Assume it's a module name directly
|
|
7219
|
+
module_name = path
|
|
7220
|
+
|
|
7221
|
+
if module_name:
|
|
7222
|
+
if is_python:
|
|
7223
|
+
imports.append(f'from includecpp import {module_name}')
|
|
7224
|
+
click.secho(f"Auto-importing: {module_name}", fg='cyan')
|
|
7225
|
+
else:
|
|
7226
|
+
includes.append(f'#include "{module_name}.h"')
|
|
7227
|
+
click.secho(f"Auto-including: {module_name}.h", fg='cyan')
|
|
7228
|
+
|
|
7229
|
+
# Show header
|
|
7230
|
+
click.echo()
|
|
7231
|
+
click.secho(f"=== IncludeCPP {lang_name} REPL ===", fg='cyan', bold=True)
|
|
7232
|
+
click.echo("Enter code line by line. Press ENTER on empty line to execute.")
|
|
7233
|
+
click.echo("Press CTRL+C to cancel.")
|
|
7234
|
+
click.echo()
|
|
7235
|
+
|
|
7236
|
+
# Show pre-loaded imports
|
|
7237
|
+
if imports:
|
|
7238
|
+
click.secho("Pre-loaded:", fg='green')
|
|
7239
|
+
for imp in imports:
|
|
7240
|
+
click.echo(f" {imp}")
|
|
7241
|
+
click.echo()
|
|
7242
|
+
|
|
7243
|
+
if includes:
|
|
7244
|
+
click.secho("Pre-loaded:", fg='green')
|
|
7245
|
+
for inc in includes:
|
|
7246
|
+
click.echo(f" {inc}")
|
|
7247
|
+
click.echo()
|
|
7248
|
+
|
|
7249
|
+
# Collect code lines
|
|
7250
|
+
lines = []
|
|
7251
|
+
prompt = '>>> ' if is_python else 'cpp> '
|
|
7252
|
+
continuation = '... ' if is_python else ' > '
|
|
7253
|
+
|
|
7254
|
+
try:
|
|
7255
|
+
while True:
|
|
7256
|
+
try:
|
|
7257
|
+
# Determine prompt
|
|
7258
|
+
current_prompt = prompt if not lines else continuation
|
|
7259
|
+
line = input(current_prompt)
|
|
7260
|
+
|
|
7261
|
+
# Empty line = execute
|
|
7262
|
+
if not line.strip():
|
|
7263
|
+
if lines:
|
|
7264
|
+
break
|
|
7265
|
+
continue
|
|
7266
|
+
|
|
7267
|
+
lines.append(line)
|
|
7268
|
+
|
|
7269
|
+
except EOFError:
|
|
7270
|
+
break
|
|
7271
|
+
|
|
7272
|
+
except KeyboardInterrupt:
|
|
7273
|
+
click.echo()
|
|
7274
|
+
click.secho("Cancelled.", fg='yellow')
|
|
7275
|
+
return
|
|
7276
|
+
|
|
7277
|
+
if not lines:
|
|
7278
|
+
click.secho("No code entered.", fg='yellow')
|
|
7279
|
+
return
|
|
7280
|
+
|
|
7281
|
+
# Build full code
|
|
7282
|
+
code_lines = imports + [''] + lines if imports else lines
|
|
7283
|
+
|
|
7284
|
+
click.echo()
|
|
7285
|
+
click.secho("--- Output ---", fg='green')
|
|
7286
|
+
|
|
7287
|
+
if is_python:
|
|
7288
|
+
# Execute Python code
|
|
7289
|
+
full_code = '\n'.join(code_lines)
|
|
7290
|
+
try:
|
|
7291
|
+
# Use exec with captured output
|
|
7292
|
+
import io
|
|
7293
|
+
from contextlib import redirect_stdout, redirect_stderr
|
|
7294
|
+
|
|
7295
|
+
stdout_capture = io.StringIO()
|
|
7296
|
+
stderr_capture = io.StringIO()
|
|
7297
|
+
|
|
7298
|
+
# Create execution context
|
|
7299
|
+
exec_globals = {'__name__': '__main__'}
|
|
7300
|
+
|
|
7301
|
+
with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture):
|
|
7302
|
+
exec(full_code, exec_globals)
|
|
7303
|
+
|
|
7304
|
+
stdout_val = stdout_capture.getvalue()
|
|
7305
|
+
stderr_val = stderr_capture.getvalue()
|
|
7306
|
+
|
|
7307
|
+
if stdout_val:
|
|
7308
|
+
click.echo(stdout_val, nl=False)
|
|
7309
|
+
if stderr_val:
|
|
7310
|
+
click.secho(stderr_val, fg='red', nl=False)
|
|
7311
|
+
|
|
7312
|
+
if not stdout_val and not stderr_val:
|
|
7313
|
+
click.secho("(no output)", fg='bright_black')
|
|
7314
|
+
|
|
7315
|
+
except Exception as e:
|
|
7316
|
+
click.secho(f"Error: {e}", fg='red')
|
|
7317
|
+
|
|
7318
|
+
else:
|
|
7319
|
+
# Execute C++ code
|
|
7320
|
+
# Build a complete C++ program
|
|
7321
|
+
cpp_code_lines = [
|
|
7322
|
+
'#include <iostream>',
|
|
7323
|
+
'#include <vector>',
|
|
7324
|
+
'#include <string>',
|
|
7325
|
+
'#include <algorithm>',
|
|
7326
|
+
'#include <cmath>',
|
|
7327
|
+
'using namespace std;',
|
|
7328
|
+
''
|
|
7329
|
+
]
|
|
7330
|
+
cpp_code_lines.extend(includes)
|
|
7331
|
+
cpp_code_lines.append('')
|
|
7332
|
+
cpp_code_lines.append('int main() {')
|
|
7333
|
+
|
|
7334
|
+
# Indent user code
|
|
7335
|
+
for line in lines:
|
|
7336
|
+
cpp_code_lines.append(' ' + line)
|
|
7337
|
+
|
|
7338
|
+
cpp_code_lines.append(' return 0;')
|
|
7339
|
+
cpp_code_lines.append('}')
|
|
7340
|
+
|
|
7341
|
+
full_code = '\n'.join(cpp_code_lines)
|
|
7342
|
+
|
|
7343
|
+
# Write to temp file and compile
|
|
7344
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.cpp', delete=False, encoding='utf-8') as f:
|
|
7345
|
+
f.write(full_code)
|
|
7346
|
+
cpp_file = f.name
|
|
7347
|
+
|
|
7348
|
+
exe_file = cpp_file.replace('.cpp', '.exe' if sys.platform == 'win32' else '')
|
|
7349
|
+
|
|
7350
|
+
try:
|
|
7351
|
+
# Compile
|
|
7352
|
+
compile_cmd = ['g++', '-std=c++17', '-o', exe_file, cpp_file]
|
|
7353
|
+
result = subprocess.run(compile_cmd, capture_output=True, text=True)
|
|
7354
|
+
|
|
7355
|
+
if result.returncode != 0:
|
|
7356
|
+
click.secho("Compilation Error:", fg='red')
|
|
7357
|
+
click.echo(result.stderr)
|
|
7358
|
+
else:
|
|
7359
|
+
# Run
|
|
7360
|
+
run_result = subprocess.run([exe_file], capture_output=True, text=True, timeout=10)
|
|
7361
|
+
if run_result.stdout:
|
|
7362
|
+
click.echo(run_result.stdout, nl=False)
|
|
7363
|
+
if run_result.stderr:
|
|
7364
|
+
click.secho(run_result.stderr, fg='red', nl=False)
|
|
7365
|
+
if not run_result.stdout and not run_result.stderr:
|
|
7366
|
+
click.secho("(no output)", fg='bright_black')
|
|
7367
|
+
|
|
7368
|
+
except subprocess.TimeoutExpired:
|
|
7369
|
+
click.secho("Execution timed out (10s limit)", fg='red')
|
|
7370
|
+
except FileNotFoundError:
|
|
7371
|
+
click.secho("Error: g++ not found. Install a C++ compiler.", fg='red')
|
|
7372
|
+
except Exception as e:
|
|
7373
|
+
click.secho(f"Error: {e}", fg='red')
|
|
7374
|
+
finally:
|
|
7375
|
+
# Cleanup temp files
|
|
7376
|
+
import os
|
|
7377
|
+
try:
|
|
7378
|
+
os.unlink(cpp_file)
|
|
7379
|
+
if os.path.exists(exe_file):
|
|
7380
|
+
os.unlink(exe_file)
|
|
7381
|
+
except Exception:
|
|
7382
|
+
pass
|
|
7383
|
+
|
|
7384
|
+
click.echo()
|
|
7385
|
+
click.secho("--------------", fg='green')
|
|
7386
|
+
|
|
7387
|
+
|
|
7388
|
+
# ============================================================================
|
|
7389
|
+
# CSSL - Hidden Command Group
|
|
7390
|
+
# ============================================================================
|
|
7391
|
+
|
|
7392
|
+
@click.group(hidden=True)
|
|
7393
|
+
def cssl():
|
|
7394
|
+
"""CSSL scripting commands."""
|
|
7395
|
+
pass
|
|
7396
|
+
|
|
7397
|
+
|
|
7398
|
+
@cssl.command(name='exec')
|
|
7399
|
+
@click.argument('path', required=False, type=click.Path())
|
|
7400
|
+
@click.option('--code', '-c', type=str, help='Execute code directly')
|
|
7401
|
+
def cssl_exec(path, code):
|
|
7402
|
+
"""Execute CSSL code or file."""
|
|
7403
|
+
from pathlib import Path as PathLib
|
|
7404
|
+
|
|
7405
|
+
try:
|
|
7406
|
+
from ..core.cssl_bridge import CsslLang
|
|
7407
|
+
except ImportError as e:
|
|
7408
|
+
click.secho(f"CSSL runtime not available: {e}", fg='red')
|
|
7409
|
+
return
|
|
7410
|
+
|
|
7411
|
+
cssl_lang = CsslLang()
|
|
7412
|
+
|
|
7413
|
+
# Determine source
|
|
7414
|
+
if code:
|
|
7415
|
+
source = code
|
|
7416
|
+
elif path:
|
|
7417
|
+
path_obj = PathLib(path)
|
|
7418
|
+
if not path_obj.exists():
|
|
7419
|
+
click.secho(f"File not found: {path}", fg='red')
|
|
7420
|
+
return
|
|
7421
|
+
source = path_obj.read_text(encoding='utf-8')
|
|
7422
|
+
else:
|
|
7423
|
+
# Interactive mode
|
|
7424
|
+
click.secho("=== CSSL REPL ===", fg='magenta', bold=True)
|
|
7425
|
+
click.echo("Enter CSSL code. Empty line to execute. CTRL+C to cancel.")
|
|
7426
|
+
click.echo()
|
|
7427
|
+
|
|
7428
|
+
lines = []
|
|
7429
|
+
prompt = 'cssl> '
|
|
7430
|
+
|
|
7431
|
+
try:
|
|
7432
|
+
while True:
|
|
7433
|
+
try:
|
|
7434
|
+
line = input(prompt)
|
|
7435
|
+
if not line.strip():
|
|
7436
|
+
if lines:
|
|
7437
|
+
break
|
|
7438
|
+
continue
|
|
7439
|
+
lines.append(line)
|
|
7440
|
+
except EOFError:
|
|
7441
|
+
break
|
|
7442
|
+
except KeyboardInterrupt:
|
|
7443
|
+
click.echo()
|
|
7444
|
+
click.secho("Cancelled.", fg='yellow')
|
|
7445
|
+
return
|
|
7446
|
+
|
|
7447
|
+
if not lines:
|
|
7448
|
+
click.secho("No code entered.", fg='yellow')
|
|
7449
|
+
return
|
|
7450
|
+
|
|
7451
|
+
source = '\n'.join(lines)
|
|
7452
|
+
|
|
7453
|
+
# Execute
|
|
7454
|
+
click.secho("--- Output ---", fg='green')
|
|
7455
|
+
try:
|
|
7456
|
+
result = cssl_lang.exec(source)
|
|
7457
|
+
|
|
7458
|
+
# Print output buffer
|
|
7459
|
+
for line in cssl_lang.get_output():
|
|
7460
|
+
click.echo(line)
|
|
7461
|
+
|
|
7462
|
+
if result is not None:
|
|
7463
|
+
click.echo(f"Result: {result}")
|
|
7464
|
+
|
|
7465
|
+
except Exception as e:
|
|
7466
|
+
click.secho(f"CSSL Error: {e}", fg='red')
|
|
7467
|
+
|
|
7468
|
+
click.secho("--------------", fg='green')
|
|
7469
|
+
|
|
7470
|
+
|
|
7471
|
+
@cssl.command(name='makemodule')
|
|
7472
|
+
@click.argument('path', type=click.Path(exists=True))
|
|
7473
|
+
@click.option('--output', '-o', type=click.Path(), help='Output path for .cssl-mod')
|
|
7474
|
+
def cssl_makemodule(path, output):
|
|
7475
|
+
"""Create a .cssl-mod module from Python/C++ file."""
|
|
7476
|
+
from pathlib import Path as PathLib
|
|
7477
|
+
import pickle
|
|
7478
|
+
import base64
|
|
7479
|
+
|
|
7480
|
+
path_obj = PathLib(path)
|
|
7481
|
+
suffix = path_obj.suffix.lower()
|
|
7482
|
+
|
|
7483
|
+
if suffix not in ('.py', '.cpp', '.cp', '.h'):
|
|
7484
|
+
click.secho(f"Unsupported file type: {suffix}", fg='red')
|
|
7485
|
+
click.echo("Supported: .py, .cpp, .cp, .h")
|
|
7486
|
+
return
|
|
7487
|
+
|
|
7488
|
+
# Read source
|
|
7489
|
+
source = path_obj.read_text(encoding='utf-8')
|
|
7490
|
+
|
|
7491
|
+
# Create module data
|
|
7492
|
+
module_data = {
|
|
7493
|
+
'name': path_obj.stem,
|
|
7494
|
+
'type': 'python' if suffix == '.py' else 'cpp',
|
|
7495
|
+
'source': source,
|
|
7496
|
+
'version': '1.0',
|
|
7497
|
+
}
|
|
7498
|
+
|
|
7499
|
+
# Encode as base64 pickle
|
|
7500
|
+
encoded = base64.b64encode(pickle.dumps(module_data)).decode('utf-8')
|
|
7501
|
+
|
|
7502
|
+
# Write .cssl-mod file
|
|
7503
|
+
out_path = PathLib(output) if output else path_obj.with_suffix('.cssl-mod')
|
|
7504
|
+
out_path.write_text(f"CSSLMOD1\n{encoded}", encoding='utf-8')
|
|
7505
|
+
|
|
7506
|
+
click.secho(f"Created: {out_path}", fg='green')
|
|
7507
|
+
click.echo(f" Name: {module_data['name']}")
|
|
7508
|
+
click.echo(f" Type: {module_data['type']}")
|
|
7509
|
+
|
|
7510
|
+
|
|
7511
|
+
# Register hidden cssl command group
|
|
7512
|
+
cli.add_command(cssl)
|
|
7513
|
+
|
|
7514
|
+
|
|
7136
7515
|
# ============================================================================
|
|
7137
7516
|
# Conditional Registration of Experimental Commands
|
|
7138
7517
|
# ============================================================================
|