TSD 脚本分析器可将包含开发工具包源代码的 ASCII 文本文件转换为用来建立应用程序文件的二进制格式。TSD 脚本分析器将 .kb 文件转换为 .kbc 文件。
TSD 脚本分析器可用于命令提示版本(kp.exe)与窗口化版本(kpw.exe)。
注:除 .exe 扩展名外,这两个版本在 UNIX 中完全相同。
TSD 脚本分析器搜索没有明确指定目录的源文件时,它以下列顺序检查目录:
使用下列方法之一可打开 TSD 脚本分析器:
kpw [选项] [.kb 文件 ...]
TSD 脚本分析器对话框用来指定 .kb 文件,以分析和设置分析选项。
注:在命令提示符处使用开关与在文本框中输入命令效果相同。
- “文件名”指定要分析的 .kb 文件。
- “浏览”可访问用来查找与选择源文件的对话框来代替在“文件名”中输入文件名。
- 分析选项:
~ 分析 - 只分析指定的 .kb 文件。
~ 更新 - 分析应用程序中引用的所有 .kb 文件。如果 .kbc 文件已经存在,且不比当前
源代码旧,则 TSD 脚本分析器不分析该文件。
~ 建立 - 转换在已分析的 .kb 文件中的任何 USES 段中引用的指定 .kb 文件。如果选择此选项,且
该 .kb 文件包含应用程序的输入点,则重建整个应用程序。
- “连接字符串”- 使您可设置 DBMS 连接字符串。
- “错误消息文件名”- 指定文件,该文件含有应发送的 TSD 脚本分析器生成的错误消息。如果未生成错误消息,则自动删除指定的文件。
- “接受符号”- 用于有条件转换。指定一个已添加到 TSD 脚本分析器内部数据库中的标识符,这样包含在 #IF ... #ENDIF 结构间的源文本被转换。
- “拒绝符号”- 用于有条件转换。指定一个已从 TSD 脚本分析器内部数据库中删除的标识符,这样 TSD 脚本分析器就忽略 #IF ... #ENDIF 结构间的源文本。
- “其它搜索目录”- 用来指定路径,该路径的目录已在 TSD 脚本分析器查找源文本路径时添加到所搜索的目录列表中。该路径可以由任意多个以分号分隔的全限定目录名构成。
- “交叉引用”- 指定在其中创建三个表的数据库。这些表包含有关定义与使用全局常量、类型、变量、例行程序、SQL 表、文本文件、图符文件和位图文件的信息。
- “列出文件名”- 指定发送从源文件生成的列表文件。如果未指定文件名,则该列表被发送到标准输出。
- “代码页”(仅用于 Windows) - 指定将字符串写入 .kbc 输出文件时是使用 ANSI 缺省值还是 OEM 代码页。
仅分析一个文件之前,应确保对文件所做的更改不影响其他 .kb 文件。
已对多个 .kb 文件进行了更改时,则使用“建立”选项分析整个应用程序。这样会确保分析所有已更改的 .kb 文件。
注:如果不知道已更改的 .kb 文件对其他 .kb 文件的影响,则建议选择“建立”选项。
TSD 脚本分析器的命令行版本接受下列自变量:
-a、-b、-c、-d、-e、-f、-u、-l、-m、-o、-p、-q、-s、-x、-ide 与 -help
注:通过在 softart.ini 文件中编辑 TDT KML Parser 段可自动设置 TSD 脚本分析器使用分析命令。
自变量字符后(无空格)可带一个参数,或者参数前带一个等号(=)或冒号(:)。例如,下列实例效果相同:
-uf:\sai\ea
-u=f:\sai\ea
-u:f:\sai\ea
下表列出了 TSD 脚本分析器的有效自变量。
自变量 | 值 | 注释 |
-a<identifier> | Assert | 将该标识符安装在 TSD 脚本分析器的内部数据库中,这样就转换 #IF ... #ENDIF 结构间的源文本。在专用于应用程序的文档中可找到有关 assert 符号的详细信息。 |
-b | Build | 启动 TSD 脚本分析器,以在命令提示符处转换所有指定的 .kb 文件。此外,还分析在任何 USES 段中引用的 .kb 文件。如果在分析包含应用程序 entry point 的 .kb 文件时指定 -b 选项,则 TSD 脚本分析器重建该应用程序。 |
-c <drive> <path> | n/a | 切换到指定的驱动器和目录。 |
-d <identifier> | Deny | 从 TSD 脚本分析器的内部数据库中删除该标识符,这样就忽略 #IF ... #ENDIF 结构间的源文本。 |
-e <file> | Error | 将 TSD 脚本分析器生成的错误消息发送到指定文件。如果未生成错误消息,则自动删除指定的文件。 |
-f <path> <module> .KB | Shorthand Notation | 与输入以下命令行作用相同: kp-u=<path> <module> |
-l -l <file> -l+ |
List | 生成一个源文本列表。如果指定 -l 选项,则该列表被发送到标准输出。如果指定一个文件名(-l<file>),则该列表被发送到该文件。如果指定 -l+ 选项,则该列表被发送到其文件名由 .kb 文件名与扩展名 .lst 组成的文件。(.kb 文件名可更改为操作系统的文件命名约定)。除非使用 -E 选项指定另一个错误文件,否则,由 TSD 脚本分析器生成的错误消息被写入该列表文件。 |
-m | Make | 启动 TSD 脚本分析器,以分析在应用程序中引用的 .kb 文件。如果 .kbc 文件已经存在,且不比当前源代码旧,则 TSD 脚本分析器不重新分析该文件。 |
-o <directory> -o=<directory> -o:<directory> |
n/a | 指定写入所有已生成的 kbc 文件的输出目录。缺省情况下,该分析器将 .kbc 文件生成到 .kb 文件所在的目录。 |
-p=oem -p=ansi -poem -pansi (Windows only) |
n/a | 指定将字符串写入 .kbc 输出文件时要使用的 OEM 或 ANSI 代码页。如果未在命令提示符处指定,则该分析器使用从 softart.ini 文件中读取的值。否则,使用 ANSI 代码页(在 UNIX 中为 EPSDIC。) |
-q | Quiet | 取消版权标志与进程消息的显示,否则,它们被发送到标准输出。 |
-s <string> | n/a | 将 DBMS 连接字符串设置为 <string>。 |
-u <path> | Use | 将该路径中的目录添加到 TSD 脚本分析器查找源文本,以获取 .kb 文件时所搜索的目录列表中。该路径可以由多个以分号分隔的限定目录名构成。(在 UNIX 中,使用冒号分隔目录名。) |
-x <database> | Cross-Reference | 在指定数据库中创建三个表,该数据库包含有关定义与使用全局常量、类型、变量、例行程序、SQL 表、文本文件、图符文件以及位图文件的信息。 |
-ide | IDE | 更改 TSD 脚本分析器生成的错误消息格式,这样 Tivoli 问讯台(TSD)开发工具包 IDE 就可找到出错的相应源文本。 |
-help/? | Help | 在标准输出中显示用法总结。 |
如果要分析的开发工具包源代码包含所有 IMPORT 声明,则您必须连接并注册到相应的数据库管理器,且必须与所需数据库建立连接。否则,会生成错误消息。
使用 IMPORT 声明从数据库引入数据会导致创建临时文件。引入完毕后,此文件 kmlimprt.out 被自动删除。
如果 TSD 脚本分析器意外终止,则不能完成此文件的删除。只要 TSD 脚本分析器未在运行,则可手动删除此文件。
-S 选项使您可在分析时指定数据库,并减少对该数据库源名称进行硬件编码的需要。
从命令提示符处运行 TSD 脚本分析器时,使用 -S 选项也可在分析期间指定用户标识和口令。在 sai_sql.cfg 文件中指定的所有值都被忽略。
使用 -S 选项的首选方法是在 sai_sql.cfg 文件中指定所有值(用户标识和口令除外)。然后,在分析时,输入这些值。例如:
-S"UID=UserId; PWD=Password"
其中,UserId 是用户标识,而 Password 是用户的唯一口令。
开发工具包语言可使 .kb 文件相互使用。当 .kb 文件相互使用时,每个 .kb 文件都定义一个记录类型,该类型是由另一个 .kb 文件访问的。这就导致循环使用。换句话说,如果 B 已经使用 A 的 PUBLIC 段,则 .kb 文件 A 不能使用 .kb 文件 B 的 PUBLIC 段。开发工具包支持循环用法,但 TSD 脚本分析器不支持该用法。
为避免循环使用,可将所有受影响的记录声明移到一个由两个原始 .kb 文件使用的单独 .kb 文件中。然后,这两个原始 .kb 文件就能继续引用彼此的变量与例行程序。
下表总结了 TSD 脚本分析器报告的错误情况。(这些错误是图形窗口分析器与命令行中的常见错误。)
注意:缺少分号会造成很多错误。如果遇到您不明白的错误,请确保已使用分号。
错误 | 说明 |
$CURRENT 不是数组的有效索引。 | 曾试图用特殊索引 $CURRENT 给数组表达式加索引。该索引仅对列表表达式有效。 |
$EVENT 未定义在<function>范围内。 | 该函数不是事件句柄,且未嵌在事件句柄范围内,因此,与事件处理有关的符号未被定义。 |
$EVENTPARM 未定义在<function>范围内。 | 该函数不是事件句柄,且未嵌在事件句柄范围内,因此,与事件处理有关的符号未被定义。 |
$HANDLE 未定义在<function>范围内。 | 该函数不是事件句柄,且未嵌在事件句柄范围内,因此,与事件处理有关的符号未被定义。 |
当 $NullHandler 用作<creation routine>的自变量时,它不可有初始化自变量。 | 在给定的创建例行程序中使用 $NullHandler 时,为其输入一个初始化自变量没有意义。 |
没有匹配的 #IF,却遇到了 #ELSE。 | TSD 脚本分析器未遇到匹配的 #IF 指令,却读到该预处理器指令。 |
没有匹配的 #IF,却遇到了 #ENDIF。 | 未看到匹配的 #IF 指令,却读到了这些预处理器指令之一。 |
<name>不是定义的类型。 | 在需要指定类型的环境中遇到给定名称。 |
<name>不是给定记录类型的字段。 | 按名称引用某一字段的表达式给出一个不属于该记录中任何字段的名称。 |
<name>不是函数或过程。 | 调用表达式引用一个不是例行程序的对象。 |
缺少逗号(,)。 | TSD 脚本分析器未遇到所需的逗号。 |
发生文件写错误。 | 打开操作成功之后,文件写操作失败。通常指示内部软件错误。 |
必须指定参数输入协议(VALue 或 REFerence)。 | 必须在形式参数声明前加一个 VAL 或 REF 关键字,以指定调用例行程序时使用哪个协议。 |
WHEN 语句中所有选择器的类型必须相同。 | 具有多个选择器的 WHEN 子句中的某个选择器(多个选择器)与 WHEN 子句中的其他选择器类型不同。 |
需要事件处理函数。 | 只有事件处理函数可输入到窗口、对话框与其他事件生成对象的创建例行程序中。 |
遇到不需要的分隔符。 | 形式参数列表中的最后规范结尾有一个不需要的逗号。 |
函数<routine>的自变量 #<n>(<name>)无效。 | 自变量的类型与相应形式参数的类型不匹配。 |
要求使用常量表达式。 | 当前环境中要求使用常量表达式。 |
在<name>范围内从未引用常量<name>。 | 已声明该常量,但未使用它。 |
未找到匹配行<n>上指令的 #ENDIF。 | TSD 脚本分析器到达源文件的结尾,但找不到匹配给定行上 #IF 或 #ELSE 的 #ENDIF 指令。 |
<name>的事件句柄类型与 forward 声明不匹配。 | 事件句柄的 FORWARD 或 PUBLIC 声明指定了一个不同于该声明中所指定的事件类型。(WINDOW 是要处理的缺省事件类型。) |
不能用返回类型声明事件句柄<name>。 | 作为事件句柄声明的例行程序不能有指定的返回类型。事件句柄总返回一个整数。如果不返回任何值,则 1 为缺省值。 |
事件处理函数<name>不处理由<creation routine>创建的对象生成的事件类型。 | 窗口事件句柄不能处理进程对象的事件,反之亦然。 |
事件处理函数<name>不能有一个以上的形式参数。 | 给定事件句柄是用一个以上的形式参数声明的。 |
事件处理函数只能出现在最外层。 | 事件句柄不能嵌套在另一个例行程序内。 |
表达式不引用可访问位置。 | 分配(或影响某一对象的值的其他表达式)要求运行一个可访问与可变对象。 |
不能通过引用来传送表达式。 | 不向可访问与可屏蔽对象赋值的表达式不能作为 REF 参数传送。 |
<variable_name>的 forward 声明与<Routine_name>的 forward 声明不匹配。 | PUBLIC ROUTINES 段与 PRIVATE ROUTINES 段不匹配。请确保每一段中的自变量都匹配且为同一数据类型。 |
Forward 函数<function>没有有效实现。 | 该函数已被公开声明或通过 FORWARD 声明来说明,但这些声明无效。 |
fread() in flex scanner 失败。 | 源 .kb 文件打开之后不可读。这种情况通常是由软盘或网络故障引起的。 |
函数<name>缺少一个返回类型声明。 | 作为函数声明的例行程序必须有返回类型。 |
从未在<name>范围内引用函数<name>。 | 已声明该例行程序,但未使用它。 |
不能在过程环境中调用函数<name>。 | 指定的函数返回一个不能忽略的值。 |
在<file>中的第<n>行检测到 INTERNAL ERROR。 | 在 TSD 脚本分析器内存在错误情况。请注意文件名和行号,并与 Tivoli Systems 客户技术支持人员联系。 |
无效 $EXPORT 注释。有效注释为:LITTLE_ENDIAN、INTEL、BIG_ENDIAN、ASCII、EBCDIC、CUSTOM_CONVERT(...)和 CTYPE(...)。 | 有效注释列表中未列入的注释出现在某一记录声明的 $EXPORT 子句中。 |
从类型<type-1>到类型<type-2>的强制转换无效。 | 在当前环境中的两个类型之间进行强制转换无效。 |
在 FOR 循环中出现无效控制表达式。 | FOR 语句只能在整数范围和列表内容上迭代。 |
无效声明。 | 在 TSD 脚本分析器期望找到声明的位置发现无效语法。 |
无效表达式。 | 在 TSD 脚本分析器期望找到表达式的环境中发现语法错误。 |
无效表达式类型。 | 需要一个不同类型。 |
无效字段注释。 | 发现不能用于某一字段的注释。LITTLE_ENDIAN、INTEL、BIG_ENDIAN、CUSTOM_CONVERT(...)和 FILL(...)注释在此环境中无效。 |
无效标识符:<string>。 | 在命令提示符处指定的标识符(作为 .kb 文件名或 -a 或 -d 选项的一部分)不符合开发工具包标识符的词法规范。 |
<op>运算符的操作对象无效。 | 运算符要求使用一个不同类型的操作对象。 |
无效选项:<???>。 | TSD 脚本分析器遇到一个未知命令提示开关。 |
无效伪字段注释。 | 发现不能用于某伪字段的注释。在此环境中只有 FILL(...)和 VALUE(...)注释合法。 |
符号<symbol>的重新声明无效。 | 该符号在同一范围内有一个以上定义。 |
无效语句。 | 在需要语句处发现语法错误。请确保已使用所需分号。 |
无效类型规范。 | 在所需类型规范处发现语法错误。 |
无效 WHEN 语句表达式类型。 | WHEN 语句只能选择 INTEGER 或 STRING 类型。 |
KB 文件<kb-1>引用在 .kb 文件<kb-2>中定义的类型<typename>, 但不在它使用的 .kb 文件中列出<kb-2>。 |
没有进行相应定义就引用类型。当一个 .kb 文件中定义的记录包含在第二个 .kb 文件中定义的类型字段,而第三个.kb 文件使用第一个 .kb 文件来代替第二个 .kb 文件,以试图访问该字段时,通常出现这种情况。 |
.KB 文件名<name-1>与外部所知的它的名称(<name-2>)不匹配。 | 在 .kb 文件开头 KNOWLEDGEBASE 声明中的名称与从命令行或通过另一个 .kb 文件中的 USES 声明访问的名称不匹配。 |
函数<function>的参数数量与 FORWARD 声明不匹配。 | 某一函数的 FORWARD 或 public 声明指定的参数数量与有效声明指定的参数数量不同。 |
<parameter>的参数声明与<function>的 FORWARD 声明不匹配。 | 某一函数的 FORWARD 或 public 声明指定的参数与有效声明指定的参数不同(类型不同或参数传输协议不同)。 |
参数名称<name-1>与函数<function>的 FORWARD 声明中的<name-2>不匹配。 | 与有效声明相比,某一函数的 FORWARD 或 public 声明在一个不同的名称下指定了相同的形式参数。 |
从未引用函数<function>的参数<name>。 | 该参数已声明,但未使用它。 |
过程函数<name>没有 $RESULT。 | 不能在作为过程声明的例行程序内引用 $RESULT 伪变量。 |
不能用返回类型声明过程<name>。 | 作为过程声明的例行程序不能有返回类型。 |
选择器<value>不能在一个 WHEN 语句中多次出现。 | 每个选择器只能在一个 WHEN 语句中出现一次。 |
指定的大小(-<n>)不能为负数。 | 数组或列表是用一个值为负数的初始大小声明的。 |
在<.kb file-1>和<.kb file-2>中都定义了符号<symbol>。 | 在两个 .kb 文件中同时以 public 方式定义了给定符号。当第二个定义遮盖第一个定义时,出现此警告。 |
符号<symbol>未定义。 | 该符号未被定义就已在表达式或声明中使用。 |
符号<symbol 或 variable name>未定义。 | 在 ACTIONS 段中使用的变量未在 VARIABLES 段中以本地方式、全局方式或在 USES 链中声明。 |
必须通过引用传送事件句柄的自变量。 | 未通过 REF 关键字指定事件句柄的形式参数。 |
<symbol>的声明缺少一个冒号(:)分隔符。 | 该声明中缺少一个冒号分隔符。 |
<symbol>的声明缺少 IS 关键字。 | 该声明中缺少 IS 关键字。 |
不能重新定义预定义的符号<symbol>。 | 该符号已在开发工具包语言中预定义,不能通过应用程序代码给出一个新定义。 |
定义的类型过多(超过 65000 个)。 | 在 TSD 脚本分析器中存在内部错误。 |
从未在<name>的范围内引用类型<name>。 | 该类型已声明,但未使用它。 |
类型<type>不是 RECORD 类型。 | 当前环境中要求使用记录类型。 |
不能索引类型<type>。 | 曾试图索引一个不是数组、列表或字符串类型的表达式。 |
初始化自变量 #<n>的类型无效。 | 初始化自变量的类型与相应参数、字段或元素的类型不匹配。 |
由<function>返回的类型与 forward 声明不匹配。 | 某一函数的 FORWARD 或 public 声明指定的返回类型与有效声明指定的返回类型不同。 |
在<file>中的第<m>行不能分配<n>字节的块。 | TSD 脚本分析器在分析可能导致操作系统锁定的源代码时用尽内存。除非为 n 提供的值非常大(这可能指示一个内部错误),否则,此消息很少见(除非正在运行调试堆管理器)。内存用尽的唯一方式是用尽交换空间。 |
不能将值<v>强制作为类型<type>。 | TSD 脚本分析器不能将常量值强制作为指定类型。 |
不能 IMPORT <view>,错误代码 = <n>。 | IMPORT 声明失败。不能与数据库建立连接,或机器不能连接和注册到相应的数据库管理器。 |
找不到文件<file>。 | TSD 脚本分析器找不到指定文件。目录包括开发工具包 i420.dll 所在的当前目录以及在 SAIPATH 与 dpath 环境变量中或通过 -u 命令提示自变量指定的目录。 |
无法使<path>成为当前目录。 | 用 -c 命令提示开关指定的目录不可访问。 |
无法打开文件<file>。 | 文件打开操作失败。这种情况可能是由相应权限造成的。 |
不需要的选择器类型。 | WHEN 子句中的选择器类型与控制表达式的类型不匹配。 |
遇到无法识别的字符<char>。 | 发现无法识别的字符。 |
无法识别的预处理器指令。 | 发现以一个 '#' 字符开始的行,且指令是除 #ASSERT、#DENY、#IF、#IFNOT、#ELSE 或 #ENDIF 之外的指令。 |
在第<n>行上开始的注释未终结。 | 到达源文件的结尾,未发现与给定行的 ';(*'; 序列匹配的 ';*)'; 字符序列。 |
字符串未终结。 | 到达行的结尾,却找不到关闭字符串文字的引号字符。 |
在第 12 行的列 0 处或附近发现未设陷阱语法错误。 | 缺少关键字 ROUTINES,文件顶部的关键字 KNOWLEDGEBASE 拼写错误,或 ACTIONS、WHILE 或 IF 段之一缺少一个 END 语句。 |
从未在<name>的范围内引用变量<name>。 | 该变量已声明,但未使用它。 |
<type>初始化程序的自变量数量错误。 | 该类型的初始化程序需要另一数量的自变量(可能少)。 |
函数<name>的自变量数量错误。 | 指定的例行程序所需的自变量数量与调用表达式中提供的数量不同。 |
函数<procedure_name>的自变量数量错误。需要<number>。收到<number>。 | 在 .kb 文件的 ACTIONS 段中调用过程、函数或事件时,过程、函数或事件与形式定义不匹配。 |
无法找到具有<filename-1>名称的文件。却使用<filename-2>。 | 如果在 .kb 文件的 USES 段中指定一个 .kb 文件名,则此文件名应与包含 .kb 文件的文件名具有相同的大小写形式。如果不是如此,而 TSD 脚本试图找到它,如果继续下去,则显示此消息。 注:在以后的发行版中不支持这种情况。 |
WinSetMousePointer 需要非过时语法。用 WinSetWaitPointer 替换 WinSetMousePointer。 | 版本 4.2 与其前版本中的 WinSetMousePointer 语句已修改,以支持 TSD 开发工具包 5.0 中的多个窗口。为与旧语法兼容,TSD 脚本分析器将其转换为执行旧性能的新函数(WinSetWaitPointer)。 |
EXTERNAL 例行程序<routine>的链接规范说明无效(或过时)。 | 在 TSD 开发工具包 5.0(它现在是一个 32 位程序,且不再能装入 16 位 Windows DLL)中不再支持 $BC16 和 $BC32 链接规范。请使用 $C,且确保正在与 32 位 DLL 链接。 |
.KB 文件名<name>与内置函数或其他内部符号发生冲突。 | 4.2 之前的版本使您可为 .kb 文件命名一个与内部符号相同的名称。例如,导致混淆和潜在内部错误的 STRING、WinCreate、when 等等。现在 TSD 5.0 开发工具包 TSD 脚本分析器可识别与报告这种情况。请为 .kb 文件指定一个唯一名称。 |