TCL 中的 -> 运算符一般做什么,具体是用正则表达式做什么?

What does the -> operator in TCL do in general and with regexp in specific?

代码摘录如下:

#
# search the header for the base addresses of my slaves and other interesting properties
#
puts ""
puts "Searching \"$system_header_file_path\" for various system information..."

set C_M_N   [ string toupper $console_master_name ]

set sysid_base_re       "^\[ \t\]*#define\[ \t\]+$C_M_N\_SYSID_BASE\[ \t\]+(0x\[0-9a-fA-F\]+)"
set sysid_id_re         "^\[ \t\]*#define\[ \t\]+$C_M_N\_SYSID_ID\[ \t\]+(\[0-9a-fA-F\]+)u"
set sysid_timestamp_re  "^\[ \t\]*#define\[ \t\]+$C_M_N\_SYSID_TIMESTAMP\[ \t\]+(\[0-9a-fA-F\]+)u"
set build_id_base_re    "^\[ \t\]*#define\[ \t\]+$C_M_N\_BUILD_ID_BASE\[ \t\]+(0x\[0-9a-fA-F\]+)"
set gate_base_re        "^\[ \t\]*#define\[ \t\]+$C_M_N\_GATE_BASE\[ \t\]+(0x\[0-9a-fA-F\]+)"
set define_re           "^\[ \t\]*#define\[ \t\]+.*"

set sysid_base              "unknown"
set sysid_id                "unknown"
set sysid_timestamp         "unknown"
set build_id_base           "unknown"
set gate_base               "unknown"

set header_file [ open $system_header_file_path r ]
while { [ gets $header_file next_line ] >= 0 } {
    if { [ regexp $define_re $next_line ] } {
        if { [ regexp $sysid_base_re $next_line -> value ] } {
            set sysid_base              $value
        } elseif { [ regexp $sysid_id_re $next_line -> value ] } {
            set sysid_id                $value
        } elseif { [ regexp $sysid_timestamp_re $next_line -> value ] } {
            set sysid_timestamp         $value
        } elseif { [ regexp $build_id_base_re $next_line -> value ] } {
            set build_id_base           $value
        } elseif { [ regexp $gate_base_re $next_line -> value ] } {
            set gate_base           $value
        }
    }
}
close $header_file

我正在努力弄清楚这些事情:

文件I/O

  1. open 命令是以文本文件还是二进制文件打开文件?如果以文本文件打开,如何改为以二进制文件打开?
  2. 如何获取 $header_file 导致从文件中读取下一行? header_file 是某种文件指针吗?
  3. 为什么要检查gets返回的值是否>=0,难道TCL没有eof函数吗?

正则表达式

  1. 正则表达式命令行中使用的 -> 运算符是什么?据我所知,正则表达式命令也可以在没有这个运算符的情况下使用。

这是一个 4 个不同的问题,所以如果它最终因为需要更多关注而被关闭,请不要感到惊讶。无论如何...

文件I/O

  1. open 默认使用文本模式,将 to/from 转换为基于您的语言环境的字符编码。在打开方式中加入b以二进制方式打开,或者打开后使用fconfigure $header_file -translation binaryopen.

    的帮助中有详细信息
  2. 变量header_file 包含一个符号,tcl i/o 函数将其转换为内部文件描述符。 gets 的第一个参数是其中一个描述符的名称。

  3. gets 有两个参数 returns 读取的字符数(或二进制模式下的字节数),或 -1 尝试读取时文件结尾(或者如果在 non-blocking 模式下没有可用的完整行)。您可以有空行,即 return 0。如果您不希望遇到空行,使用 > 而不是 >= 循环可能是合适的;取决于你在做什么。 gets.

    帮助中的详细信息

正则表达式:

  1. -> 不是 运算符 ,而是 变量名 。当您只关心捕获的子表达式时,将它与用于保存整个匹配的参数中的 regexp 一起使用只是一种约定。