cppgolf 0.1.0__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.
cppgolf-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: cppgolf
3
+ Version: 0.1.0
4
+ Summary: C++ multi-file merge & code golf / minifier tool
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/yourname/cppgolf
7
+ Project-URL: Issues, https://github.com/yourname/cppgolf/issues
8
+ Keywords: cpp,c++,golf,minify,code-golf,competitive-programming
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Code Generators
18
+ Classifier: Topic :: Text Processing :: Filters
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: tree-sitter>=0.25
22
+ Requires-Dist: tree-sitter-cpp>=0.23
23
+ Provides-Extra: dev
24
+ Requires-Dist: build; extra == "dev"
25
+ Requires-Dist: twine; extra == "dev"
26
+ Requires-Dist: pytest; extra == "dev"
27
+
28
+ # CPPGolf
29
+
30
+ C++ 多文件合并 + 代码高尔夫(压缩)工具,专为竞技编程场景设计。
31
+
32
+ ## 安装
33
+
34
+ ```bash
35
+ pip install cppgolf
36
+ ```
37
+
38
+ ## CLI 用法
39
+
40
+ ```bash
41
+ cppgolf solution.cpp # 输出到 stdout
42
+ cppgolf solution.cpp -o golf.cpp # 输出到文件
43
+ cppgolf solution.cpp -I include/ -o out.cpp
44
+ cppgolf solution.cpp --rename # 符号压缩
45
+ ```
46
+
47
+ ### 选项
48
+
49
+ | 选项 | 说明 |
50
+ |------|------|
51
+ | `-o FILE` | 输出文件(默认 stdout) |
52
+ | `-I DIR` | 追加 include 搜索目录(可多次) |
53
+ | `--no-merge` | 跳过 `#include "..."` 内联 |
54
+ | `--no-strip-comments` | 保留注释 |
55
+ | `--no-compress-ws` | 保留空白格式 |
56
+ | `--no-std-ns` | 不添加 `using namespace std` |
57
+ | `--no-typedefs` | 不添加 `ll`/`ld` 等类型宏 |
58
+ | `--keep-main-return` | 保留 `return 0;` |
59
+ | `--keep-endl` | 保留 `endl` |
60
+ | `--keep-inline` | 保留 `inline` 关键字 |
61
+ | `--aggressive` | 去除单语句 if/for/while 花括号 |
62
+ | `--shortcuts` | 高频 cout/cin → `#define` 缩写 |
63
+ | `--rename` | 变量/成员名压缩为 a/b/aa/… |
64
+ | `--stats` | 显示压缩率统计 |
65
+
66
+ ## Python API
67
+
68
+ ```python
69
+ from cppgolf import process
70
+ from pathlib import Path
71
+
72
+ result = process(
73
+ Path("solution.cpp"),
74
+ include_dirs=[], # 额外的 #include 搜索目录
75
+ rename_symbols=True,
76
+ )
77
+ print(result)
78
+ ```
79
+
80
+ 也可单独使用各 pass:
81
+
82
+ ```python
83
+ from cppgolf import strip_comments, compress_whitespace, golf_rename_symbols
84
+
85
+ code = open("a.cpp").read()
86
+ code = strip_comments(code)
87
+ code = golf_rename_symbols(code)
88
+ code = compress_whitespace(code)
89
+ ```
90
+
91
+ ## 功能说明
92
+
93
+ - **合并**:递归内联 `#include "..."` 本地头文件,去除 include guard / `#pragma once`,系统头去重
94
+ - **去注释**:状态机感知字符串,支持 `//`、`/* */`、原始字符串 `R"(...)"`
95
+ - **语义压缩**:`std::` 消除、`long long→ll` 宏、`endl→"\n"`、去 `return 0;`、去 `inline`
96
+ - **空白压缩**:token 级最小化,代码压为单行,预处理行保留换行
97
+ - **符号重命名**:tree-sitter AST 驱动,仅重命名用户自定义变量/参数/成员名,不碰函数名/类型名/命名空间
@@ -0,0 +1,70 @@
1
+ # CPPGolf
2
+
3
+ C++ 多文件合并 + 代码高尔夫(压缩)工具,专为竞技编程场景设计。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install cppgolf
9
+ ```
10
+
11
+ ## CLI 用法
12
+
13
+ ```bash
14
+ cppgolf solution.cpp # 输出到 stdout
15
+ cppgolf solution.cpp -o golf.cpp # 输出到文件
16
+ cppgolf solution.cpp -I include/ -o out.cpp
17
+ cppgolf solution.cpp --rename # 符号压缩
18
+ ```
19
+
20
+ ### 选项
21
+
22
+ | 选项 | 说明 |
23
+ |------|------|
24
+ | `-o FILE` | 输出文件(默认 stdout) |
25
+ | `-I DIR` | 追加 include 搜索目录(可多次) |
26
+ | `--no-merge` | 跳过 `#include "..."` 内联 |
27
+ | `--no-strip-comments` | 保留注释 |
28
+ | `--no-compress-ws` | 保留空白格式 |
29
+ | `--no-std-ns` | 不添加 `using namespace std` |
30
+ | `--no-typedefs` | 不添加 `ll`/`ld` 等类型宏 |
31
+ | `--keep-main-return` | 保留 `return 0;` |
32
+ | `--keep-endl` | 保留 `endl` |
33
+ | `--keep-inline` | 保留 `inline` 关键字 |
34
+ | `--aggressive` | 去除单语句 if/for/while 花括号 |
35
+ | `--shortcuts` | 高频 cout/cin → `#define` 缩写 |
36
+ | `--rename` | 变量/成员名压缩为 a/b/aa/… |
37
+ | `--stats` | 显示压缩率统计 |
38
+
39
+ ## Python API
40
+
41
+ ```python
42
+ from cppgolf import process
43
+ from pathlib import Path
44
+
45
+ result = process(
46
+ Path("solution.cpp"),
47
+ include_dirs=[], # 额外的 #include 搜索目录
48
+ rename_symbols=True,
49
+ )
50
+ print(result)
51
+ ```
52
+
53
+ 也可单独使用各 pass:
54
+
55
+ ```python
56
+ from cppgolf import strip_comments, compress_whitespace, golf_rename_symbols
57
+
58
+ code = open("a.cpp").read()
59
+ code = strip_comments(code)
60
+ code = golf_rename_symbols(code)
61
+ code = compress_whitespace(code)
62
+ ```
63
+
64
+ ## 功能说明
65
+
66
+ - **合并**:递归内联 `#include "..."` 本地头文件,去除 include guard / `#pragma once`,系统头去重
67
+ - **去注释**:状态机感知字符串,支持 `//`、`/* */`、原始字符串 `R"(...)"`
68
+ - **语义压缩**:`std::` 消除、`long long→ll` 宏、`endl→"\n"`、去 `return 0;`、去 `inline`
69
+ - **空白压缩**:token 级最小化,代码压为单行,预处理行保留换行
70
+ - **符号重命名**:tree-sitter AST 驱动,仅重命名用户自定义变量/参数/成员名,不碰函数名/类型名/命名空间
@@ -0,0 +1,46 @@
1
+ """
2
+ cppgolf — C++ multi-file merge & code golf tool
3
+
4
+ 公开 API:
5
+ process(input_file, include_dirs, **options) -> str
6
+ golf_rename_symbols(code) -> str
7
+ strip_comments(code) -> str
8
+ merge_files(filepath, include_dirs, visited, sys_includes) -> str
9
+ compress_whitespace(code) -> str
10
+ golf_std_namespace / golf_typedefs / golf_endl_to_newline /
11
+ golf_remove_main_return / golf_remove_inline /
12
+ golf_braces_single_stmt / golf_define_shortcuts
13
+ """
14
+
15
+ from .strip_comments import strip_comments
16
+ from .merge import merge_files, strip_include_guard
17
+ from .whitespace import compress_whitespace
18
+ from .transforms import (
19
+ golf_std_namespace,
20
+ golf_typedefs,
21
+ golf_remove_main_return,
22
+ golf_endl_to_newline,
23
+ golf_remove_inline,
24
+ golf_braces_single_stmt,
25
+ golf_define_shortcuts,
26
+ )
27
+ from .golf_rename import golf_rename_symbols
28
+ from .__main__ import process
29
+
30
+ __all__ = [
31
+ "process",
32
+ "strip_comments",
33
+ "merge_files",
34
+ "strip_include_guard",
35
+ "compress_whitespace",
36
+ "golf_std_namespace",
37
+ "golf_typedefs",
38
+ "golf_remove_main_return",
39
+ "golf_endl_to_newline",
40
+ "golf_remove_inline",
41
+ "golf_braces_single_stmt",
42
+ "golf_define_shortcuts",
43
+ "golf_rename_symbols",
44
+ ]
45
+
46
+ __version__ = "0.1.0"
@@ -0,0 +1,148 @@
1
+ """cppgolf.__main__ — CLI 入口,支持 python -m cppgolf 和 cppgolf 命令"""
2
+ import sys
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ from .strip_comments import strip_comments
7
+ from .merge import merge_files
8
+ from .whitespace import compress_whitespace
9
+ from .transforms import (
10
+ golf_std_namespace, golf_typedefs, golf_remove_main_return,
11
+ golf_endl_to_newline, golf_remove_inline,
12
+ golf_braces_single_stmt, golf_define_shortcuts,
13
+ )
14
+ from .golf_rename import golf_rename_symbols
15
+
16
+
17
+ def process(
18
+ input_file: Path,
19
+ include_dirs: list,
20
+ *,
21
+ no_merge: bool = False,
22
+ no_strip_comments: bool = False,
23
+ no_compress_ws: bool = False,
24
+ no_std_ns: bool = False,
25
+ no_typedefs: bool = False,
26
+ keep_main_return: bool = False,
27
+ keep_endl: bool = False,
28
+ keep_inline: bool = False,
29
+ aggressive: bool = False,
30
+ define_shortcuts: bool = False,
31
+ rename_symbols: bool = False,
32
+ ) -> str:
33
+ sys_includes: list = []
34
+ visited: set = set()
35
+
36
+ if not no_merge:
37
+ merged = merge_files(input_file, list(include_dirs), visited, sys_includes)
38
+ code = ''.join(sys_includes) + merged
39
+ else:
40
+ code = input_file.read_text(encoding='utf-8-sig', errors='replace')
41
+
42
+ if not no_strip_comments:
43
+ code = strip_comments(code)
44
+
45
+ if not keep_endl:
46
+ code = golf_endl_to_newline(code)
47
+ if not no_std_ns:
48
+ code = golf_std_namespace(code)
49
+ if not no_typedefs:
50
+ code = golf_typedefs(code)
51
+ if not keep_main_return:
52
+ code = golf_remove_main_return(code)
53
+ if not keep_inline:
54
+ code = golf_remove_inline(code)
55
+ if aggressive:
56
+ code = golf_braces_single_stmt(code)
57
+ if define_shortcuts:
58
+ code = golf_define_shortcuts(code)
59
+ if rename_symbols:
60
+ code = golf_rename_symbols(code)
61
+
62
+ if not no_compress_ws:
63
+ code = compress_whitespace(code)
64
+
65
+ return code.strip() + '\n'
66
+
67
+
68
+ def build_parser() -> argparse.ArgumentParser:
69
+ p = argparse.ArgumentParser(
70
+ prog='cppgolf',
71
+ description='C++ 多文件合并 + 代码高尔夫工具',
72
+ formatter_class=argparse.RawDescriptionHelpFormatter,
73
+ epilog="""示例:
74
+ cppgolf solution.cpp
75
+ cppgolf solution.cpp -o golf.cpp
76
+ cppgolf solution.cpp -I include/ --rename --stats
77
+ """,
78
+ )
79
+ p.add_argument('input', type=Path, help='入口 C++ 文件')
80
+ p.add_argument('-o', '--output', type=Path, default=None, help='输出文件(默认 stdout)')
81
+ p.add_argument('-I', '--include', dest='include_dirs', action='append',
82
+ type=Path, default=[], metavar='DIR', help='追加 include 目录(可多次)')
83
+
84
+ g = p.add_argument_group('功能开关(默认全部开启)')
85
+ g.add_argument('--no-merge', action='store_true', help='跳过多文件合并')
86
+ g.add_argument('--no-strip-comments', action='store_true', help='保留注释')
87
+ g.add_argument('--no-compress-ws', action='store_true', help='保留空白格式')
88
+ g.add_argument('--no-std-ns', action='store_true', help='不添加 using namespace std')
89
+ g.add_argument('--no-typedefs', action='store_true', help='不添加 ll/ld 等类型宏')
90
+ g.add_argument('--keep-main-return', action='store_true', help='保留 main 末尾 return 0')
91
+ g.add_argument('--keep-endl', action='store_true', help='保留 endl')
92
+ g.add_argument('--keep-inline', action='store_true', help='保留 inline 关键字')
93
+
94
+ g2 = p.add_argument_group('激进优化(有风险,默认关闭)')
95
+ g2.add_argument('--aggressive', action='store_true',
96
+ help='单语句 if/for/while 去花括号')
97
+ g2.add_argument('--shortcuts', dest='define_shortcuts', action='store_true',
98
+ help='高频 cout/cin 用 #define 缩写')
99
+ g2.add_argument('--rename', dest='rename_symbols', action='store_true',
100
+ help='将用户变量/成员名压缩为短名(需要 tree-sitter-cpp)')
101
+
102
+ p.add_argument('--stats', action='store_true', help='显示压缩率统计')
103
+ return p
104
+
105
+
106
+ def main():
107
+ parser = build_parser()
108
+ args = parser.parse_args()
109
+
110
+ if not args.input.exists():
111
+ print(f'错误:文件不存在 —— {args.input}', file=sys.stderr)
112
+ sys.exit(1)
113
+
114
+ original_size = args.input.stat().st_size
115
+ result = process(
116
+ args.input, args.include_dirs,
117
+ no_merge=args.no_merge,
118
+ no_strip_comments=args.no_strip_comments,
119
+ no_compress_ws=args.no_compress_ws,
120
+ no_std_ns=args.no_std_ns,
121
+ no_typedefs=args.no_typedefs,
122
+ keep_main_return=args.keep_main_return,
123
+ keep_endl=args.keep_endl,
124
+ keep_inline=args.keep_inline,
125
+ aggressive=args.aggressive,
126
+ define_shortcuts=args.define_shortcuts,
127
+ rename_symbols=args.rename_symbols,
128
+ )
129
+
130
+ def print_stats(final_size: int):
131
+ ratio = (1 - final_size / original_size) * 100 if original_size else 0
132
+ print(f'[统计] 原始:{original_size} B → 高尔夫后:{final_size} B (压缩 {ratio:.1f}%)',
133
+ file=sys.stderr)
134
+
135
+ if args.output:
136
+ args.output.write_text(result, encoding='utf-8')
137
+ if args.stats:
138
+ print_stats(args.output.stat().st_size)
139
+ else:
140
+ print(f'已写入:{args.output}', file=sys.stderr)
141
+ else:
142
+ if args.stats:
143
+ print_stats(len(result.encode('utf-8')))
144
+ sys.stdout.write(result)
145
+
146
+
147
+ if __name__ == '__main__':
148
+ main()