// 共享库一览 —— 用 **C++** 把四个共享库各叫一遍
// Shared libraries tour -- calling all four shared libraries from **C++**
int main() {
//
// ◆ 这份例程在练什么
// ◆ What this example exercises
//
// 共享库是**一次投入、22 门语言都受益**的那种东西：`regex`（正则）· `dbf`（dBASE 数据文件）
// · `sql`（跑在 .dbf 上的查询）· `turtle`（海龟作图）。它们**不是 C++ 的库**，
// 而是每一门语言都能调的同一份实现 —— 这份例程就是"从 C++ 这边调得动"的活证据。
// The shared libraries are one investment serving all 22 languages: `regex`, `dbf` (dBASE data
// files), `sql` (queries over .dbf) and `turtle`. They are not C++ libraries -- they are one
// implementation every language can call. This example is the living proof that C++ can.
//
//   regex  : 模式 `abc` 在 `xxabcyy` 里**找得到**吗（1 = 找得到）
//   dbf    : 现建一张两字段的表、塞两条记录，再看一眼记录数
//   sql    : 在刚建的那张表上跑一句 `SELECT ... WHERE`
//   turtle : 抬笔走 50 步，看它的坐标（不写屏幕，所以**不需要开窗口**）
//
// ◆ 为什么全程只调"返回整数"的那些接口
// ◆ Why only the integer-returning calls
//
// C++ 的字符串**不可变** ⇒ 传不出一个可写缓冲区，而 `dbf_get` / `sql_cell` 这类要调用方
// 给 dst。所以这里走另一条路：**需要缓冲区的地方用 `alloc()` 自己拿一块地址**
// （见下面建记录那几句），取值一律用"只问长度"的形态（`dbf_fname(h, f, 0)`）。
// C++ strings are immutable, so there is no writable buffer to hand to `dbf_get`/`sql_cell`.
// Two ways around it: take an address yourself with `alloc()` (see the record-building lines),
// and use the "length only" form of the accessors (`dbf_fname(h, f, 0)`).
//
// ⚠ 跑一次会在**本文件所在目录**建一个 `libdemo.dbf`（这就是 dbf 那一半在演示的事）。
// ⚠ Running this creates a small `libdemo.dbf` **next to this file** -- that is the point of it.

// ── regex：模式匹配 ──
print_str("REGEX_HIT=");
println_int(re_test("abc", "xxabcyy"));
print_str("REGEX_MISS=");
println_int(re_test("abc", "xxabxyy"));
print_str("REGEX_VALID=");
println_int(re_is_valid("(a|b)+"));

// ── dbf：建表 → 塞两条 → 读记录数 ──
// 字段类型用**字符的字节值**：'C' = 67（字符型）· 'N' = 78（数字型）——
// C++ 没有字符字面量，所以这里直接写数字。
auto h = dbf_new("libdemo.dbf");
dbf_addfield(h, "NAME", 67, 8, 0);
dbf_addfield(h, "AGE", 78, 3, 0);
dbf_build(h);

auto rec = alloc(64);
dbf_mkrec(h, rec);
dbf_put(h, rec, 0, "Alice");
dbf_put(h, rec, 1, "30");
dbf_add(h, rec);
dbf_mkrec(h, rec);
dbf_put(h, rec, 0, "Bob");
dbf_put(h, rec, 1, "7");
dbf_add(h, rec);
dbf_flush(h);

print_str("DBF_ROWS=");
println_int(dbf_records(h));
print_str("DBF_FIELDS=");
println_int(dbf_fields(h));
print_str("DBF_FIELD0_LEN=");
println_int(dbf_fname(h, 0, 0));
dbf_close(h);

// ── sql：在刚建的表上查 ──
print_str("SQL_ROWS=");
println_int(sql_run("libdemo.dbf", "SELECT * FROM t WHERE AGE > 20"));
print_str("SQL_COLS=");
println_int(sql_cols());
print_str("SQL_COL0_LEN=");
println_int(sql_colname(0, 0));

// ── turtle：抬笔走 50 步（落笔会去画屏幕，那要窗口）──
turtle_reset();
turtle_pen_up();
turtle_forward(50);
print_str("TURTLE_X=");
println_int(turtle_x());
print_str("TURTLE_Y=");
println_int(turtle_y());

// ── sed：sed 的替换规则（s / y 两条命令，依附 regex 库）—— 缓冲区那一半只有 C 拿得到，
//    这里压的是「只问长度」那一支（cap 传 0）与对账用的 sed_count。
print_str("SED_COUNT=");
println_int(sed_count("s/a/X/g", "banana"));
print_str("SED_LEN=");
println_int(sed_sub("s/a/X/g", "banana", 0, 0));
print_str("DONE=");
println_int(1);

// 期望（scripts/lib-examples-check.sh 按这一行比对）：
// EXPECT: REGEX_HIT=1|REGEX_MISS=0|REGEX_VALID=1|DBF_ROWS=2|DBF_FIELDS=2|DBF_FIELD0_LEN=4|SQL_ROWS=1|SQL_COLS=2|SQL_COL0_LEN=4|TURTLE_X=0|TURTLE_Y=50|SED_COUNT=3|SED_LEN=6|DONE=1

return 0;
}
