-
Notifications
You must be signed in to change notification settings - Fork 35
[200_60] Goldfish Scheme 支持忽略 shebang #652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # [200_60] Goldfish Scheme 支持 shebang | ||
|
|
||
| ## 2026/04/03 在 load_file_1 中实现 shebang 跳过逻辑 | ||
|
|
||
| ### What | ||
| 在 `load_file_1` 函数中添加 shebang 行跳过逻辑,使 Goldfish Scheme 能够正确执行以 `#!` 开头的脚本文件。 | ||
|
|
||
| ### Why | ||
| shebang(`#!`)是 Unix-like 系统中用于指定脚本解释器的机制。用户希望能够直接运行 Goldfish Scheme 脚本,例如: | ||
|
|
||
| ```scheme | ||
| #!/usr/bin/env goldfish | ||
| (display "Hello, World!") | ||
| ``` | ||
|
|
||
| 在实现 shebang 支持之前,Goldfish 会将 `#!` 解析为注释或错误语法,导致脚本无法直接执行。 | ||
|
|
||
| ### How | ||
| 在 `load_file_1` 函数中,加载文件内容后、解析执行前,检查文件内容是否以 `#!` 开头: | ||
|
|
||
| 1. 检查端口数据是否以 `#` 和 `!` 开头 | ||
| 2. 如果是,则循环查找第一个换行符 `\n` | ||
| 3. 找到换行符后,将端口位置设置为换行符之后的位置,跳过 shebang 行 | ||
| 4. 如果没有找到换行符(文件只有 shebang 一行),则将位置设置为文件末尾 | ||
|
|
||
| ## 任务相关的代码文件 | ||
| - `src/s7.c` - 修改 `load_file_1` 函数,添加 shebang 跳过逻辑 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28935,6 +28935,21 @@ static s7_pointer load_file_1(s7_scheme *sc, const char *filename) | |
| port_file_number(port) = remember_file_name(sc, (local_file_name) ? local_file_name : filename); | ||
| if (local_file_name) free(local_file_name); | ||
| set_loader_port(port); | ||
| /* 跳过 shebang 行:如果文件以 #! 开头,跳过第一行 */ | ||
| if (is_string_port(port) && | ||
| port_data_size(port) >= 2 && | ||
| port_data(port)[0] == '#' && | ||
| port_data(port)[1] == '!') | ||
| { | ||
| uint8_t *data = port_data(port); | ||
| s7_int pos = 0; | ||
| while (pos < port_data_size(port) && data[pos] != '\n') | ||
| pos++; | ||
| if (pos < port_data_size(port)) /* 找到换行符,跳过它 */ | ||
| port_position(port) = pos + 1; | ||
| else /* 没有换行符,文件只有 shebang 行 */ | ||
| port_position(port) = port_data_size(port); | ||
| } | ||
|
||
| push_input_port(sc, port); | ||
| return(port); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shebang-skip logic is guarded by
is_string_port(port), but on Windows,read_filealways creates afile_port(not astring_port) — see the#elsebranch starting at line 27577 insrc/s7.c. This means the#!line is never skipped on Windows, and the interpreter will encounter a syntax error when loading a shebang script on that platform.The Windows-specific branch sets
port_data = NULLandport_data_size = 0, so theis_string_portguard correctly prevents a NULL-dereference crash, but the feature silently fails to work.If Windows shebang support is needed, a separate code path for
file_port(usinggetc/ungetcor similar) would be required. If Windows is intentionally out of scope, a comment here would clarify the limitation.