Cobol 如何获取当前段落名称?

Cobol 如何获取当前段落名称?,cobol,Cobol,我想知道如何在这里使用MVS Enterprise COBOL V4.2获取COBOL中的当前段落名称 假设我在程序部分有以下代码: MAIN-LOGIC. MOVE SPACE TO ABT-MSG PERFORM PARAGRAPH-1 PERFORM PARAGRAPH-2 GO TO CLOSE-PROGRAM. * * SEARCH FOR A VALUE IN AN ARRAY AND GET THE RELATE

我想知道如何在这里使用MVS Enterprise COBOL V4.2获取COBOL中的当前段落名称

假设我在程序部分有以下代码:

   MAIN-LOGIC.
       MOVE SPACE TO ABT-MSG
       PERFORM PARAGRAPH-1
       PERFORM PARAGRAPH-2
       GO TO CLOSE-PROGRAM.
  *
  * SEARCH FOR A VALUE IN AN ARRAY AND GET THE RELATED INDEX
  *
   PARAGRAPH-1.
       MOVE 42 TO SEARCH-VALUE
       PERFORM VARYING I-SEARCH FROM 1 BY 1
           UNTIL SOME-ARRAY(I-SEARCH) = SEARCH-VALUE
         IF (I-SEARCH = MAX-ARRAY-POSITION)
           MOVE SEARCH-ABORT TO ABT-MSG
           MOVE 'PARAGRAPH-1' TO ABT-LOC
           GO TO CLOSE-PROGRAM
         END-IF
       END-PERFORM
       DISPLAY 'VALUE WAS FOUND AT POSITION ' I-SEARCH '.'.
  *
  * STORE A NEW VALUE AT THE END OF AN ARRAY
  *
   PARAGRAPH-2.
       MOVE 42 TO STORAGE-VALUE
       ADD 1 TO I-STORAGE
       IF (I-STORAGE > MAX-ARRAY-POSITION)
         MOVE STORAGE-ABORT TO ABT-MSG
         MOVE 'PARAGRAPH-2' TO ABT-LOC
         GO TO CLOSE-PROGRAM
       END-IF
       MOVE STORAGE-VALUE TO SOME-ARRAY(I-STORAGE).
  *
  * CLOSE THE PROGRAM
  *
   CLOSE-PROGRAM.
       IF ABT-MSG > SPACE
         DISPLAY ABT-MSG
         DISPLAY '(FOUND IN ' ABT-LOC ')'
         MOVE 20 TO RETURN-CODE
       ELSE
         DISPLAY SUCCESS-MESSAGE
       END-IF
       STOP RUN.
我希望能够访问当前的段落名称并将其存储在ABT-LOC中,而不必编写它。 是否有一个COBOL系统变量来执行此操作,如“CURR-PARA-NAME”或其他什么

多谢各位

---更新1----


我已经更新了我的代码示例,使其更加具体。 要知道,在我真正的COBOL程序中,有各种搜索中止和存储中止的可能性,我正在处理许多数组

我希望使我的代码尽可能好,因此我将访问当前段落的名称,而不必编写它

再次感谢你

----更新2---

那好吧。看来我做不到我的程序的用户可能会拒绝任何他们不习惯得到的调试消息-仅供参考,我正在用非常非常糟糕的编程实践重写一个有50年历史的程序,例如向上的GO-TOs、fall-through logic和被上帝抛弃的ALTER,我希望在最后得到相同的输出

别担心,今晚我不会哭的。这只是对我的代码在美学上的改进,没有它我可以活下去。我的代码已经比我基于自己的代码漂亮多了


我感谢大家抽出时间,并祝你们过得愉快。。。堆积如山

由于您使用了伪代码,这里发生了一些不好的事情,我假设出现了一个异常。在这种情况下,标准COBOL 2002、COBOL 2014函数异常位置可能会有所帮助,尽管实际字符串是由实现者定义的,但我假设段落可能在其中[GnuCOBOL的格式为:程序id;段落[或节或节的段落,取决于您的程序];源代码行]

如果您的COBOL编译器在这个函数中提供了这些信息,并且在有问题的部分中已经没有异常:通过从无符号变量中减去1或类似的方法创建一个

正如Bill已经说过或暗示的:如果您必须将名称作为标识符和标签,那么实际使用的COBOL编译器将是最重要的部分

了解实际COBOL编译器后进行编辑:

IBM MVS Enterprise COBOL没有异常定位功能。因此,我只看到一个内置解决方案:

DECLARATIVES.
debug-declaratives SECTION.
   USE FOR DEBUGGING ON ALL PROCEDURES.
debug-par.
    MOVE debug-name  TO current-procedure.
END DECLARATIVES.
但由于这仅在程序以调试模式运行时才处于活动状态,这可能会导致出现大量调试消息,因此我不建议实际使用它


尝试使用提供宏的编辑器或在实际源代码上运行shell脚本,以创建随后传递给编译器的源代码。

由于您有伪代码,我假设这里发生了错误。在这种情况下,标准COBOL 2002、COBOL 2014函数异常位置可能会有所帮助,尽管实际字符串是由实现者定义的,但我假设段落可能在其中[GnuCOBOL的格式为:程序id;段落[或节或节的段落,取决于您的程序];源代码行]

如果您的COBOL编译器在这个函数中提供了这些信息,并且在有问题的部分中已经没有异常:通过从无符号变量中减去1或类似的方法创建一个

正如Bill已经说过或暗示的:如果您必须将名称作为标识符和标签,那么实际使用的COBOL编译器将是最重要的部分

了解实际COBOL编译器后进行编辑:

IBM MVS Enterprise COBOL没有异常定位功能。因此,我只看到一个内置解决方案:

DECLARATIVES.
debug-declaratives SECTION.
   USE FOR DEBUGGING ON ALL PROCEDURES.
debug-par.
    MOVE debug-name  TO current-procedure.
END DECLARATIVES.
但由于这仅在程序以调试模式运行时才处于活动状态,这可能会导致出现大量调试消息,因此我不建议实际使用它


尝试使用提供宏的编辑器或在实际源代码上运行shell脚本,以创建随后传递给编译器的源代码。

正如Simon Sobisch在其回答中正确指出的那样,要完全实现您想要的功能,唯一的方法就是使用调试声明。请参阅后面的答案,了解如何使其起作用,但任何人都不应允许您对生产程序执行此操作

COBOL是一种编译语言,因此除非编译器提供某些可用的内容,否则不会自动访问任何数据名或过程名段落或节。除上述情况外,情况并非如此

剩下的三种方法是:手动执行您希望避免的操作,就像桃子一样,确保有人在不更改文本的情况下复制或重新定位代码;使用程序或编辑器进行预处理,以自动使用正确的标签填充字段;做点别的

既然你暗中贬低了第一,我再一次正确地认为,让我们考虑第二个问题。如果在同一段落/章节中有两个、三个或八个内容都是业务错误,尽管通常是 ese类型的东西更多的是完整性错误,一种不应该存在的状态,所以不要继续

由于您将得到这些,预处理解决方案开始变得更加丑陋

还可以做些什么

这是我们多年来一直面临的问题。答案是,在程序错误编号中是唯一的。每个错误都可以被命名,并给出一个数字。命名良好的错误引用很难正确使用。添加新错误时,很难复制现有编号。或者,换句话说,它很容易复制,但在测试中却很容易被发现——嘿,这是1234,这是错误的

它绝不是防弹的,但是数据名和任何相关的文本都比段落名更好地说明了问题,而段落名除了人为地指出错误是什么,只是指出了错误的位置。在程序中很容易找到错误引用,从中很容易找到过程名称,除非您实际上不再需要它

带有错误号的程序是否超过了手动维护的将“文字”移动到某些标准名称程序的糟粕,这是未知的。但是你可以猜出我喜欢和推荐哪一种

现在,如何使用声明为企业COBOL实现这一点

   IDENTIFICATION DIVISION. 
   PROGRAM-ID. STAB39. 
   ENVIRONMENT DIVISION. 
   CONFIGURATION SECTION. 
   SOURCE-COMPUTER. FRED DEBUGGING MODE. 

   DATA DIVISION. 
   WORKING-STORAGE SECTION. 
   01  W-WHEN-COMPILED                     PIC X(8)BX(8).
   01  ABT-LOC                             PIC X(30). 


   PROCEDURE DIVISION. 
  DDECLARATIVES. 
  DSOME-SECTION SECTION. 
  D    USE FOR DEBUGGING ON ALL PROCEDURES 
  D    . 
  DSOME-PARA. 
  D    MOVE DEBUG-NAME TO ABT-LOC 
  D    . 
  DEND DECLARATIVES. 
   STARTING-UP SECTION. 
       DISPLAY 
               ABT-LOC 
  D    DISPLAY 
  D            "IT IS STARTING UP" 
       MOVE WHEN-COMPILED           TO W-WHEN-COMPILED 
       DISPLAY 
               "STAB39 " 
               W-WHEN-COMPILED 
       . 
   A-PARA. 
       DISPLAY 
               ABT-LOC 
       PERFORM 
         10 TIMES 
  D        DISPLAY 
                   "ITERATING" 
       END-PERFORM 
       . 
   ANOTHER-PARA. 
       DISPLAY 
               ABT-LOC 
       PERFORM                      THE-PARA 
                                     10 TIMES 
       PERFORM                      THE-SECOND-PARA 
       GOBACK 
       . 
   THE-PARA. 
       DISPLAY 
               ABT-LOC 
       . 
   THE-SECOND-PARA. 
       DISPLAY 
               ABT-LOC
       . 
一些注意事项:

源计算机段需要使用COBOL内置调试功能来启用它们。因此,还需要环境部门和配置部门。示例中的计算机名FRED是必需的,但与此无关。如果你喜欢的话,你可以用你最喜欢的宠物或亲戚的名字来命名你的电脑,或者把任何东西放在那里,那里一定有东西

声明只能在过程部分的开头指定。它们必须在一节内,所有动作必须在属于一节的段落内。章节和段落的名称无关紧要,但无论如何都要使它们有意义

由于声明必须包含节,因此如果第一个过程标签不是节,您将收到一条信息性诊断消息。这不需要在程序中使用段落上的节,它没有进一步的效果

第七列中的D表示调试行。这些行仅在您使用源计算机段落启用调试时生成代码

本程序练习段落的所有用法,本例中除GO TO外,章节的用法没有什么不同。“转到”的段落将产生与任何其他参考相同的结果,但您不会在我的程序中看到“转到”:-

可以使用声明词而不是使用所有过程来命名要捕获的一个或多个过程

例如,您可能有多个调试过程,如果希望设置测试条件,可以在其中包含大量代码

尽管这个特性在COBOL中已经存在很长时间了,但可以公平地说它并没有得到广泛的应用,特别是在特定的调试产品可用的情况下

仅仅有这个程序是不够的,如果不是默认的,运行时需要打开调试。z/OS上的运行时称为语言环境,由多种语言共享,以便于语言间的通信。语言包括C/C++、PL/I和Java以及COBOL。有语言环境例程和宏可用于使HLASM/Assembler程序与LE兼容,以提供现成的接口

要查看站点的默认运行时选项,最简单的方法是在运行JCL中包含CEEOPTS DD语句

//CEEOPTS  DD  *
   RPTOPTS(ON) 
这将列出用于Enclave跑步环境的所有选项,并指出每个选项的来源

如果在选项列中看到NODEBUG,则默认情况下关闭COBOL调试。要为特定运行启用该选项,请执行以下操作:

//CEEOPTS  DD  *
   DEBUG 
这将允许执行所有带D标签的调试行和调试声明

这将实现您想要的功能,但是没有人会允许一个正在调试的程序进入生产环境,因此您无法将其用于您想要的功能

按照优先顺序,我建议错误编号和测试、自动化、手工编码的过程名称文本

IBM对其所有产品都进行了完整的文档记录,您可以找到EnterpriseCoblV4.2的文档语言参考和编程指南,以及z/OS发行版的多个语言环境

最后一点。不要使用“转到”来中断正常的处理流程。使用PERFORM。即使在逻辑上,PERFORM不能返回。使用GO TO将关闭包含GO TO的段落/节的编译器优化,这很容易对执行造成明显影响。这与IBM COBOL确保执行的段落/节的状态不为pre之前的建议相反
在两次通话之间提供服务。当时正确的建议是使用GO to。这不再是正确的建议。

正如Simon Sobisch在其回答中正确指出的那样,要完全实现您想要的功能,唯一的方法就是使用调试声明。请参阅后面的答案,了解如何使其起作用,但任何人都不应允许您对生产程序执行此操作

COBOL是一种编译语言,因此除非编译器提供某些可用的内容,否则不会自动访问任何数据名或过程名段落或节。除上述情况外,情况并非如此

剩下的三种方法是:手动执行您希望避免的操作,就像桃子一样,确保有人在不更改文本的情况下复制或重新定位代码;使用程序或编辑器进行预处理,以自动使用正确的标签填充字段;做点别的

既然你暗中贬低了第一,我再一次正确地认为,让我们考虑第二个问题。如果在同一段落/章节中有两个、三个或八个内容都是业务错误,尽管这些类型的内容通常都是完整性错误,这种状态不应该存在,所以不要继续

由于您将得到这些,预处理解决方案开始变得更加丑陋

还可以做些什么

这是我们多年来一直面临的问题。答案是,在程序错误编号中是唯一的。每个错误都可以被命名,并给出一个数字。命名良好的错误引用很难正确使用。添加新错误时,很难复制现有编号。或者,换句话说,它很容易复制,但在测试中却很容易被发现——嘿,这是1234,这是错误的

它绝不是防弹的,但是数据名和任何相关的文本都比段落名更好地说明了问题,而段落名除了人为地指出错误是什么,只是指出了错误的位置。在程序中很容易找到错误引用,从中很容易找到过程名称,除非您实际上不再需要它

带有错误号的程序是否超过了手动维护的将“文字”移动到某些标准名称程序的糟粕,这是未知的。但是你可以猜出我喜欢和推荐哪一种

现在,如何使用声明为企业COBOL实现这一点

   IDENTIFICATION DIVISION. 
   PROGRAM-ID. STAB39. 
   ENVIRONMENT DIVISION. 
   CONFIGURATION SECTION. 
   SOURCE-COMPUTER. FRED DEBUGGING MODE. 

   DATA DIVISION. 
   WORKING-STORAGE SECTION. 
   01  W-WHEN-COMPILED                     PIC X(8)BX(8).
   01  ABT-LOC                             PIC X(30). 


   PROCEDURE DIVISION. 
  DDECLARATIVES. 
  DSOME-SECTION SECTION. 
  D    USE FOR DEBUGGING ON ALL PROCEDURES 
  D    . 
  DSOME-PARA. 
  D    MOVE DEBUG-NAME TO ABT-LOC 
  D    . 
  DEND DECLARATIVES. 
   STARTING-UP SECTION. 
       DISPLAY 
               ABT-LOC 
  D    DISPLAY 
  D            "IT IS STARTING UP" 
       MOVE WHEN-COMPILED           TO W-WHEN-COMPILED 
       DISPLAY 
               "STAB39 " 
               W-WHEN-COMPILED 
       . 
   A-PARA. 
       DISPLAY 
               ABT-LOC 
       PERFORM 
         10 TIMES 
  D        DISPLAY 
                   "ITERATING" 
       END-PERFORM 
       . 
   ANOTHER-PARA. 
       DISPLAY 
               ABT-LOC 
       PERFORM                      THE-PARA 
                                     10 TIMES 
       PERFORM                      THE-SECOND-PARA 
       GOBACK 
       . 
   THE-PARA. 
       DISPLAY 
               ABT-LOC 
       . 
   THE-SECOND-PARA. 
       DISPLAY 
               ABT-LOC
       . 
一些注意事项:

源计算机段需要使用COBOL内置调试功能来启用它们。因此,还需要环境部门和配置部门。示例中的计算机名FRED是必需的,但与此无关。如果你喜欢的话,你可以用你最喜欢的宠物或亲戚的名字来命名你的电脑,或者把任何东西放在那里,那里一定有东西

声明只能在过程部分的开头指定。它们必须在一节内,所有动作必须在属于一节的段落内。章节和段落的名称无关紧要,但无论如何都要使它们有意义

由于声明必须包含节,因此如果第一个过程标签不是节,您将收到一条信息性诊断消息。这不需要在程序中使用段落上的节,它没有进一步的效果

第七列中的D表示调试行。这些行仅在您使用源计算机段落启用调试时生成代码

本程序练习段落的所有用法,本例中除GO TO外,章节的用法没有什么不同。“转到”的段落将产生与任何其他参考相同的结果,但您不会在我的程序中看到“转到”:-

可以使用声明词而不是使用所有过程来命名要捕获的一个或多个过程

例如,您可能有多个调试过程,如果希望设置测试条件,可以在其中包含大量代码

尽管这个特性在COBOL中已经存在很长时间了,但可以公平地说它并没有得到广泛的应用,特别是在特定的调试产品可用的情况下

仅仅有这个程序是不够的,如果不是默认的,运行时需要打开调试。z/OS上的运行时称为语言环境,由多种语言共享,以便于语言间的通信。语言包括C/C++、PL/I和Java以及COBOL。有语言环境例程和宏可用于使HLASM/Assembler程序与LE兼容,以提供现成的接口

要查看站点的默认运行时选项,最简单的方法是在运行JCL中包含CEEOPTS DD语句

//CEEOPTS  DD  *
   RPTOPTS(ON) 
这将列出用于Enclave跑步环境的所有选项,并指出每个选项的来源

如果,在 选项列,您将看到NODEBUG,然后默认情况下关闭COBOL调试。要为特定运行启用该选项,请执行以下操作:

//CEEOPTS  DD  *
   DEBUG 
这将允许执行所有带D标签的调试行和调试声明

这将实现您想要的功能,但是没有人会允许一个正在调试的程序进入生产环境,因此您无法将其用于您想要的功能

按照优先顺序,我建议错误编号和测试、自动化、手工编码的过程名称文本

IBM对其所有产品都进行了完整的文档记录,您可以找到EnterpriseCoblV4.2的文档语言参考和编程指南,以及z/OS发行版的多个语言环境



最后一点。不要使用“转到”来中断正常的处理流程。使用PERFORM。即使在逻辑上,PERFORM不能返回。使用GO TO将关闭包含GO TO的段落/节的编译器优化,这很容易对执行造成明显影响。这与IBM COBOL确保在调用之间不保留已执行段落/节的状态之前的建议相反。当时正确的建议是使用GO to。这不再是正确的建议。

你在使用哪种COBOL编译器?就像比尔说的那样。GnuCOBOL中有一个新的ish扩展来公开某些托管变量,我只是做了一个小实验来返回指向步骤跟踪数据的指针。包括当前程序id。还有其他方法可以获取该id、节、段落、源文件和行号。似乎是对CBL_OC_HOSTED的一个有价值的添加,但确实需要在编译期间为可执行文件设置-ftrace或-ftraceall以跟踪步骤跟踪程序数据。当它进入时,将使用返回err指示符的paraptr段落调用承载的CBL_OC_。成功时,paraptr设置为char*。@你应该写出来。我走的是另一条路线…始终可以选择添加您自己的预编译步骤。或者,根据您的编辑器,您可以设置编辑宏。ispfeditor/rexx适用于这样的事情。我怀疑这可以在jedit和其他一些高级编辑器中实现,你使用的是哪种COBOL编译器?比如比尔,他说。GnuCOBOL中有一个新的ish扩展来公开某些托管变量,我只是做了一个小实验来返回指向步骤跟踪数据的指针。包括当前程序id。还有其他方法可以获取该id、节、段落、源文件和行号。似乎是对CBL_OC_HOSTED的一个有价值的添加,但确实需要在编译期间为可执行文件设置-ftrace或-ftraceall以跟踪步骤跟踪程序数据。当它进入时,将使用返回err指示符的paraptr段落调用承载的CBL_OC_。成功时,paraptr设置为char*。@你应该写出来。我走的是另一条路线…始终可以选择添加您自己的预编译步骤。或者,根据您的编辑器,您可以设置编辑宏。ispfeditor/rexx适用于这样的事情。我怀疑这可以在jedit和其他一些高级编辑器中实现。我已经用更具体的情况更新了我的代码示例。我不认为它们是异常,而是业务错误。是的,调试声明是唯一可行的方法,它不应该这样做。您给了我一个我不能应用的有效解决方案,所以我会把您的答案标记为最有用的。您好。我已经用更具体的情况更新了我的代码示例。我不认为它们是异常,而是业务错误。是的,调试声明是唯一可行的方法,它不应该这样做。您给了我一个我不能应用的有效解决方案,所以我会把您的答案标记为最有用的。您好。您是对的:错误的位置通常不足以解决所述错误。有时我在一个段落中会有几种中止的可能性。我使用段落名称的目的是帮助我或用户更快地发现错误。但这一目标可以通过其他方式实现,比如——正如你所说的——为每种错误类型设置唯一的错误编号。顺便说一句,即使我不会将您的代码用于声明,我也很感激。在COBOL上,你显然比我知道得多,而且你似乎知道自己在说什么。你好!您是对的:错误的位置通常不足以解决所述错误。有时我在一个段落中会有几种中止的可能性。我使用段落名称的目的是帮助我或用户更快地发现错误。但这一目标可以通过其他方式实现,比如——正如你所说的——为每种错误类型设置唯一的错误编号。顺便说一句,即使我不会将您的代码用于声明,我也很感激。在COBOL上,你显然比我知道得多,而且你似乎知道自己在说什么。你好!