13b3ebbe14
把川大 wiki「02.Qt方向」课程代码整理为 CMake 管理的可编译运行项目。
Part1 C/C++ 强化 (p01/, 144 目标, host gcc/g++ 构建, 全绿):
- 修复全部编译失败:补 <cstring>/<fstream>/<iomanip>/<vector> 等缺失头
(common_fix + infer_stl_includes 自动检测注入)、修正 pause() 壳注入
(改检测已转换后的 pause 调用)、namespace 提升出函数体、const 成员函数
正确性、dedupe 不再破坏函数重载集、K&R 隐式 int / 动态异常规范等
C++17 移除特性的可编译等价改写。
- 目录采用深缩写 p01/ch04/s03/ (原 part1_cpp/ch04_class_object/03_ctor_dtor)。
Part3 Qt 桌面 (p03/, 29 目标, 隔离 Qt 5.14.2 构建, 全绿):
- gen_part3.py: Qt 外壳模板 (main+QApplication+show, QTimer 自动退出便于
offscreen 验证)、AUTOMOC + .moc include、rewrite_* 处理散文混入/重载/
资源依赖、生成占位 png/gif + .qrc + rundata 样例数据。
- 修正 QLable 笔误、全角分号、.→->、Windows 路径、QApplication 阻塞事件
循环改为 QCoreApplication 等。
任务1 概念/版本验证:
- tools/std_probe.py: 跨 -std= 编译探针 (--pedantic-errors 让已废除特性硬失败)。
- tools/demo_versions/: K&R 隐式 int、三目左值、void* 转换、enum 赋整、
const 经指针、动态异常规范 共 6 个跨版本演示。
- docs/VERSION_NOTES.md: 每条「原文说法→C17/C++17 是否成立→何版本成立→已验证」。
文档: 顶层 README、docs/SOURCE_PAGES.md (页面→目录映射)、
docs/ERRATA.md (Part1 修正)、docs/ERRATA_part3.md (Part3 修正)。
另修复 tools/run.sh / run_qt.sh 的 ${1:?...} 引号语法 bug。
隔离 Qt 验证: ldd 0 系统 Qt 引用; 173/173 目标全绿; p03 offscreen 运行通过。
100 lines
4.7 KiB
Python
100 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
# ==============================================================================
|
|
# std_probe.py — 快速演示「同一段代码在不同语言标准下的支持情况」
|
|
#
|
|
# 用途(对应任务 1):把一段 C 或 C++ 代码片段,在多个 -std= 下逐个编译,报告
|
|
# pass / fail / warnings,从而直观看到「某概念在哪个版本成立」。
|
|
#
|
|
# 用法:
|
|
# tools/std_probe.py --lang c --code 'int main(){ __auto_type x=1; return x; }'
|
|
# tools/std_probe.py --lang c++ --file snippet.cpp
|
|
# tools/std_probe.py --lang c --file snippet.c --standards c89,c99,c11,c17,c23
|
|
#
|
|
# 说明:
|
|
# * 编译器用宿主机 gcc/g++(本仓库 gcc 13 原生支持全部目标标准)。
|
|
# * 仅做语法编译(-fsyntax-only),不链接、不运行,避免副作用。
|
|
# * 退出码:全 pass 为 0;任一 fail 为 1(便于脚本/CI 判定)。
|
|
# ------------------------------------------------------------------------------
|
|
import argparse, os, subprocess, sys, tempfile
|
|
|
|
# 默认要探测的标准列表(C 与 C++ 各一组,覆盖课程相关版本)
|
|
DEFAULTS = {
|
|
"c": ["c89", "c99", "c11", "c17", "c23"],
|
|
"c++": ["c++98", "c++03", "c++11", "c++14", "c++17", "c++20", "c++23"],
|
|
}
|
|
|
|
def probe(code: str, lang: str, standards, extra_flags=None):
|
|
"""Compile `code` under each standard in `standards` (syntax-only). Returns
|
|
list of dicts: {std, ok, warnings, errors}."""
|
|
compiler = "gcc" if lang == "c" else "g++"
|
|
results = []
|
|
extra_flags = extra_flags or []
|
|
with tempfile.NamedTemporaryFile("w", suffix=(".c" if lang == "c" else ".cpp"),
|
|
delete=False) as f:
|
|
f.write(code)
|
|
src = f.name
|
|
try:
|
|
for std in standards:
|
|
cmd = [compiler, f"-std={std}", "-fsyntax-only", "-Wall", "-Wextra"] + extra_flags + [src]
|
|
p = subprocess.run(cmd, capture_output=True, text=True)
|
|
combined = (p.stderr or "") + (p.stdout or "")
|
|
# categorize lines: gcc/clang warnings vs errors
|
|
warns = [l for l in combined.splitlines() if "warning:" in l]
|
|
errs = [l for l in combined.splitlines() if "error:" in l]
|
|
results.append({
|
|
"std": std,
|
|
"ok": p.returncode == 0,
|
|
"warnings": warns,
|
|
"errors": errs,
|
|
})
|
|
finally:
|
|
os.unlink(src)
|
|
return results
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser(description="Probe a C/C++ snippet across -std= versions.")
|
|
g = ap.add_mutually_exclusive_group(required=True)
|
|
g.add_argument("--code", help="inline code snippet")
|
|
g.add_argument("--file", help="path to a source file")
|
|
ap.add_argument("--lang", choices=["c", "c++"], required=True,
|
|
help="language (selects compiler & default standards)")
|
|
ap.add_argument("--standards", default=None,
|
|
help="comma-separated -std values (default: course-relevant set)")
|
|
ap.add_argument("--show-warnings", action="store_true",
|
|
help="print warning lines (default: only summarize)")
|
|
ap.add_argument("--pedantic-errors", action="store_true",
|
|
help="add -pedantic-errors so removed/deprecated features FAIL hard "
|
|
"(gcc otherwise lets many removed features compile as warnings)")
|
|
args = ap.parse_args()
|
|
|
|
code = args.code if args.code else open(args.file).read()
|
|
standards = args.standards.split(",") if args.standards else DEFAULTS[args.lang]
|
|
extra_flags = ["-pedantic-errors"] if args.pedantic_errors else []
|
|
|
|
print(f"Compiler : {('gcc' if args.lang=='c' else 'g++')} ({subprocess.run(['gcc','--version'],capture_output=True,text=True).stdout.splitlines()[0]})")
|
|
print(f"Language : {args.lang}")
|
|
print(f"Standards: {', '.join(standards)}"
|
|
+ (" [pedantic-errors ON]" if args.pedantic_errors else ""))
|
|
print("-" * 64)
|
|
|
|
results = probe(code, args.lang, standards, extra_flags=extra_flags)
|
|
any_fail = False
|
|
for r in results:
|
|
flag = "PASS" if r["ok"] else "FAIL"
|
|
w = f" {len(r['warnings'])} warning(s)" if r["warnings"] else ""
|
|
e = f" {len(r['errors'])} error(s)" if r["errors"] else ""
|
|
print(f" -std={r['std']:<8} : {flag}{w}{e}")
|
|
if not r["ok"]:
|
|
any_fail = True
|
|
for line in r["errors"][:3]:
|
|
print(f" {line.strip()}")
|
|
if args.show_warnings:
|
|
for line in r["warnings"][:3]:
|
|
print(f" (warn) {line.strip()}")
|
|
print("-" * 64)
|
|
print("Result : " + ("ALL PASS" if not any_fail else "SOME FAIL"))
|
|
return 1 if any_fail else 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|