Getting current line number in Cobol - cobol

Is it possible to get and display the current line number in the Cobol program?
For example, C allows do it by the next way:
...
printf("Current line = %d\n", __LINE__);
...

Short answer: No.
There is no portable COBOL way in doing this, especially not in all places like __LINE__ does.
Long answer with potential alternatives:
COBOL 2002 added intrinsic functions for exception handling. Using these you can get the location where the last error happened, which checks are activated.
You could hack something by raising a non-fatal exception and ideally in the same line use that function...
From the standard:
The EXCEPTION-LOCATION function returns an alphanumeric character string, part of which is the implementor-defined location of the statement associated with the last exception status.
So this may provide you with the line number, as the returned value depends on the implementation, additional it seems that - at the time of writing - neither IBM nor MicroFocus nor Fujitsu compilers support that intrinsic function at all.
The GnuCOBOL implementation returns a semicolon-separated list with the last entry being the line number.
The upcoming COBOL standard added the MODULE-NAME intrinsic function - but this will only give the name, not the line reference.
If you are free to choose which implementation you use, then an addition of an extra register COB_SOURCE_LINE / COB_SOURCE_FILE in GnuCOBOL should be relative easy to add...
If the intend is a tracing of some kind: many compilers have an extension READY TRACE/ RESET TRACE. With those two statements (and possibly compiler directives / options) they will at least show the name of sections and paragraphs reached, some may also show the line number. Often this could be redirected to a file and will otherwise go to the default error stream.
If you use GnuCOBOL and compile with -ftrace-all you can also use that for line or statement tracing with self-defined format as specified in COB_TRACE_FORMAT [which can also be adjusted within the COBOL program and limited to the line number].

Q: Is it possible to get and display the current line number in the Cobol program?
There was a feature through COBOL 85 called the DEBUG module. The feature was made obsolete in COBOL 85 and subsequently removed in COBOL 2002. While DEBUG lines were available in the 2002 standard, the DEBUG module was removed from the standard.
NOTE: The DEBUG module may still be available in current compilers.
The feature requires debugging mode in the source-computer paragraph. If the line is removed, source lines with a D or d in column 7 are treated as comments.
Declaratives must be added to access debug-line which is the standard name for the source line number.
I have coded the source such that the source line number of wherever I place perform show-line will be displayed. Notice that show-line doesn't do anything.
Source:
program-id. dbug.
environment division.
source-computer. computer-name debugging mode.
object-computer. computer-name.
data division.
working-storage section.
01 char pic x.
procedure division.
declaratives.
ddebug section.
duse for debugging show-line.
d display "Source-line: " debug-line.
end declaratives.
main-line.
begin.
display "Before"
d perform show-line
display "After"
accept char
stop run.
dshow-line.
end program dbug.
Each implementor has their own means for activating the feature. For the system I use, it's a switch parameter (+D) on the command line. Without the switch parameter the line number will not show. (For GnuCOBOL 3.2 it is, apparently, the environment variable COB_SET_DEBUG with a value of 'Y', 'y' or '1'. ;-))
Command line:
dbug (+D)
Display:
Before
Source-line: 17
After

Related

Multiple exit causing compiler warnings

I have a program where under several conditions I would want to exit early, rather than continuing through the flow, and rather than having to check for that exit-early condition in calling paragraphs.
To do this, I have a paragraph "EXIT-FAILURE", that checks to make sure that the general return flag field is not ok (0), logs a message (DISPLAY), and finally has the statement GOBACK.
However, doing this is giving me a compiler warning on every PERFORM that calls this "EXIT-FAILURE" paragraph:
IGYCB7310-W The "PERFORM" statement at "PERFORM (line [line-number])" cannot reach its exit.
Is there any way to have this logic (which is basically multiple-exit/early-exit rather than single-exit), without having a compiler warning?
Is this idea entirely contrary to the COBOL way of doing things (my experience is more in Java, where this would be entirely normal in the context of guard statements or exceptions)?
EDIT: Adding minimal program requested by Simon:
IDENTIFICATION DIVISION.
PROGRAM-ID. SOQUEST.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
PERFORM A100-INITIALIZE
PERFORM A200-VALIDATE
PERFORM B200-PROCESS-STEP-1
GOBACK
.
A100-INITIALIZE.
DISPLAY "INITIALIZED"
.
A200-VALIDATE.
PERFORM Z900-EXIT-FAILURE
.
B200-PROCESS-STEP-1.
DISPLAY "COMPLETED STEP 1"
.
Z900-EXIT-FAILURE.
GOBACK
.
Results in these two warnings related to my question:
IGYCB7310-W The "PERFORM" statement at "PERFORM (line 58.1)" cannot reach its exit.
IGYCB7310-W The "PERFORM" statement at "PERFORM (line 68.1)" cannot reach its exit.
(line 58.1 maps to the line "PERFORM A200-VALIDATE"; line 68.1 maps to the line "PERFORM Z900-EXIT-FAILURE")
As seen in the compiler warning and the additional explanation from the compiler manual, the issue is that you PERFORM something and PERFORM says "do this and then come back".
If Enterprise COBOL for z/OS adds support for RAISE exception-name (and ideally user-defined exceptions) this would be the way to go (both being "COBOL" as requested in the question and "exceptional" like in java) and you'd place the paragraph into DECLARATIVES as EXIT-FAILURE SECTION. USE AFTER EXCEPTION CONDITION exception-name. Until then [= maybe forever]:
If there's no rule against this on-site: use GO TO EXIT-FAILURE - this COBOL verb says "go there" (and likely don't come back, especially with a well named paragraph as in your case).
If there's a rule against GO TO - go with the approach from #cschneid - add a comment in the header about this warning and reference this comment directly where it happens with another comment.
Side-note: I personally would still try to put the paragraph into DECLARATIVES (unchanged, as it is now, just move it "up" to DECLARATIVES) to stretch the point "this is only called if something goes wrong" even more. But your compiler may raise another warning or even error in this case (at least "standard"-COBOL requires a use-statement there).
My reaction to this compiler warning would be to add a comment in the source indicating that the warning is expected. IBM Enterprise COBOL 6.3 (the latest release as of this date) does not support the RAISE statement.
It's not unlike PERFORMing a paragraph that does an EXEC CICS RETURN.
#SimonSobisch knows more about COBOL than I ever will, and will hopefully supply an example of how to solve this more in keeping with the "COBOL way" which will be useful to future seekers of knowledge here.
Using EXIT PARAGRAPH can help to avoid Go TO, compilation warnings, and comments ...
IDENTIFICATION DIVISION.
PROGRAM-ID. SOQUEST.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FLAGS.
03 WS-VALIDATION PIC 9 VALUE ZERO.
88 WS-VALIDATION-OK VALUE 0.
88 WS-VALIDATION-ERROR VALUE 1.
PROCEDURE DIVISION.
MAIN.
PERFORM A100-INITIALIZE
PERFORM A200-VALIDATE
IF WS-VALIDATION-ERROR
EXIT PARAGRAPH
END-IF
PERFORM B200-PROCESS-STEP-1
.
CLOSE-FILES.
CLOSE XXXX
CLOSE YYY
.
EXIT-PROGRAM.
GOBACK
.
A100-INITIALIZE.
DISPLAY "INITIALIZED"
.
A200-VALIDATE.
* Do next when validation fails ...
MOVE 1 TO WS-VALIDATION
ANY-VALIDATION-HERE
IF ERROR-FOUND
EXIT PARAGRAPH
END-IF
CONTINUE-WITH-OTHER-VALIDATIONS
IF ERROR-FOUND
EXIT PARAGRAPH
END-IF
* Arriving here .. MEANS VALIDATION IS ok
MOVE O TO WS-VALIDATION
.
B200-PROCESS-STEP-1.
DISPLAY "COMPLETED STEP 1"
.
Try the following:
Z900-EXIT-FAILURE.
IF <some condition that is always true>
GOBACK
END-IF
.
As long as the compiler optimizer cannot determine the fact that the IF condition is always true, it won't raise the warning message.
A response to comment below and a few other suggestions...
Compiler optimization in some future release may determine the condition to be always true and remove it:
This would cause the warning message to return. Face that problem when it occurs. For the present,
something like: IF FUNCTION WHEN-COMPILED <= FUNCTION CURRENT-DATE
will not be optimized away, and probably won't be for many years to come.
May produce less efficient code:
The whole point of this paragraph is to exit the program. The
extra instructions needed for the IF test should not have a measurable affect
on performance.
Disable the diagnostic:
This can be done using a compiler exit to catch and
nullify the message, see: https://www.ibm.com/support/knowledgecenter/en/SS6SG3_6.3.0/pg/ref/rpext10.html .
I would caution against this because valid warnings may also be suppressed, some of which
probably should not be ignored.
Put a comment in the code indicating the warning is acceptable:
Not all programmers are so diligent as to continue reviewing compiler warnings once
they find out they are sometimes acceptable. Chances are good that valid warnings will be missed
in the future.
Using DECLARATIVES:
The IBM Enterprise COBOL compiler supports DECLARATIVES for I/O related errors
and debugging only making their usage fairly restrictive. Furthermore, there are a number of additional restrictions as to whether a STOP RUNor GOBACK
may be issued while a DECLARATIVE procedure is active. I would hesitate to advise using DECLARATIVES.
Language Environment provides facilities to
establish user defined condition handling but this is a fairly advanced topic.
see: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceea800/ceea824.htm
Use GO TO Z900-EXIT-FAILURE:
GO is recognized by the compiler as a go-there-and-don't-come-back transfer of control
and will not issue message IGYCB7310-W provided the GO TO is conditionally
executed (e.g. contained within an IF or other conditional statement). This is probably the best solution provided
local coding standards permit
usage of GO TO in these circumstances. Some places have an unjustified pathological fear of GO TO
and won't allow it under any circumstances.

Reading COBOL code with .NET to generate a call graph

I am working on a project to automate COBOL to generate a class diagram. I am developing using a .NET console application. I need help tracking down the procedure name where the perform statement in used in the below example.
**Z-POST-COPYRIGHT.
move 0 to RETURN-CODE
perform Z-WRITE-FILE**
How do I track the procedure name 'Z-Post-COPYRIGHT' where the procedure 'Z-write-file' is called? The only idea I could think of in terms of COBOL is through indentation as the procedure names are always indented. Ideally in the database, the code should track the procedure name after the word 'perform' and procedure under which it is called (in this case it is Z-POST-COPYRIGHT).
I assume you want to do this "on your own" without external tools (a faster approach can be found at the end).
You first have to "know" your source:
which compiler was it compiled with (get a manual for this compiler)
which options were used
Then you have to preparse the source:
include copybooks (doing the given REPLACING rules if any)
if the source is in free-form reference format: concatenate contents of last line and current line if you find a - in column 7
check for REPLACE and change the result accordingly
remove all comments (maybe only * and \ in column 7 in fixed-form reference format or similar (extensions like "variable" format / "terminal" format", ... exist, maybe only inline comments - when in free-form reference-format, otherwise maybe inline comments *> or compiler specific extensions like |) - depending on the further re-engineering you want to do it could be a good idea to extract them and store them at least with a line number reference
The you finally can track the procedure name with the following rule:
go backwards to the last separator period (there are more rules but the rule "at least one line break, another period, a space a comma or a semicolon" [I've never seen the last two in real code but it is possible" should be enough)
check if there is only one word between this separator period and the next
if this word is no reserved COBOL word (this depends on your compiler) it is very likely a procedure name
Start from here and check the output, then fine grade the rule with actual false positives or missing entries.
If you want to do more than only extract the procedure-names for PERFORM and GO TO (you should at least check the sources for PERFROM ... THRU) then this can get to a lot of work...
Faster approach with external tools:
run a COBOL compiler on the complete sources and tell it to do the preparsing only - this way you have the big second point solved already
if you have the option: tell the compiler or an external tool to create a symbol table / cross reference - this will tell you in which line a procedure is and its name (you can simply find the correct procedure by comparing the line)
Just a note: You may want to check GnuCOBOL (formerly OpenCOBOL) for the preparsing and/or generation of symbol tables/cross-reference and/or printcbl for a completely external tool doing preparsing and/or cobxref for a complete cross reference generation.

How to get the current paragraph name?

I would like to know how to get the current paragraph name in COBOL (using MVS Enterprise COBOL V4.2 here).
Let's say I have this code in the PROCEDURE DIVISION :
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.
I would like to be able to access the current paragraph name (and store it in ABT-LOC) instead of having to write it.
Is there a COBOL system variable to do so, like 'CURR-PARA-NAME' or something ?
Thank you.
------ UPDATE 1 -------
I have updated my code example to make it more specific.
Know that, in my real COBOL program, there are various occurences of SEARCH-ABORT and STORAGE-ABORT possibilities (I am working with many arrays).
I want to make my code as good as possible, hence my will to access the current paragraph name instead of having to write it.
Thank you again.
------- UPDATE 2 ------
Well then. It seems I cannot do it (the users of my program will probably reject any debug messages they are not used to get - For your information, I am rewriting a 50 years old program with very, very bad programming practices such as upward GO TOs, fall-through logic and the godforsaken ALTER, and I want to get the same output at the end).
Don't worry, I will not cry tonight. This was just an esthetical improvement to my code, and I can live without it (my code is already a lot prettier than what I based myself on).
I thank all of you for your time, and wish you a good... Stack Overday !
As Simon Sobisch has correctly indicated in his answer, the only way to do exactly what you want is to use the "debugging declaratives". See later in the answer for making that work, but no-one should allow you to do this to a Production program.
COBOL is a compiled language so there is no no automatic access to any data-name or procedure name (paragraph or SECTION) unless the compiler makes something available. Which, excluding the case above, it doesn't.
That leaves three approaches: doing it manually (which you correctly want to avoid, as sure as peaches someone is going to copy or relocate code without changing the literal); pre-processing (with a program or the editor) to automatically populate your field with the correct label; doing something else.
Since you are implicitly discounting the first, again I believe correctly, let's consider the second. What if you have two, three or eight things in the same paragraph/SECTION which are all "business errors" (although usually these types of things are more "integrity errors", a state which should not exist, so don't continue)?
Since you will get those, a "pre-processing" solution starts to get more ugly.
What else can be done?
Well, it's something we've faced for many, many years. The answer is, unique (within the program) error numbers. The individual errors can be named, well, and given a number. The well-named error reference is difficult to use "incorrectly". When adding a new error, it is difficult to duplicate an existing number. Or, to put it another way, it is easy to duplicate but horribly easy to spot in testing - "hey, that's produced 1234, that's wrong".
It's in no way bullet-proof, but the data-name (and any associated text) give better indication of the problem than a paragraph-name (which is not going to be, except artificially, any indication of what the error is, just the location of it). The error references are very easy to find in the program, and from that it is easy to locate the procedure name, except you don't actually need it any more.
Whether the program with error-numbers outweigh the dross of manually maintained MOVE 'literal' TO some-standard-name programs is unknown. But you can guess which I favour and recommend.
Now, how to do it for Enterprise COBOL with DECLARATIVES.
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
.
Some notes:
The SOURCE-COMPUTER paragraph is required to use COBOLs in-built debugging features, to turn them on. So the ENVIRONMENT DIVISION and CONFIGURATION SECTION are also required. The "computer name", FRED in the example, is required, but it is irrelevant. You can "name" your computer after your favourite pet or relative if you like, or put anything there, there just has to be something.
DECLARATIVES can only be specified at the start of the PROCEDURE DIVISION. They must be within a SECTION and all actions must be within a paragraph belonging to a SECTION. The names of the SECTION and paragraph are irrelevant, but make them meaningful anyway.
Because the DECLARATIVES must contain a SECTION, you will be subject to an informational diagnostic message if your first procedure label is not also a SECTION. This does not require using SECTIONS over paragraphs in your program, it has no further effect.
The D in column seven indicates a "debugging line". These lines only get code generated when you turn debugging on with the SOURCE-COMPUTER paragraph.
The program exercises all use of a paragraph (and use of a SECTION is no different for this example) except GO TO. Paragraphs which are GO TO'd will produce the same results as any other reference, but you won't see GO TOs in my programs :-)
It is possible to name the procedure or procedures you want to "trap" with the DECLARATIVES instead of using "ALL PROCEDURES".
You may have multiple DEBUGGING procedures, and you can include extensive code within them if you wish (setting up conditions for testing, for instance).
Although this feature has existed in COBOL for a long time, it is probably fair to say that it is not widely used, especially as specific "debugging products" became available.
It is not enough just to have this program, the "run time" needs to have DEBUG turned on, if it is not the default. The run-time on z/OS is called Language Environment and is shared by multiple languages (allowing easy inter-language communication). Languages include C/C++, PL/I and Java as well as COBOL. There are Language Environment routines and macros available to make HLASM/Assembler programs "LE Compliant" to also provide ready interfacing.
To see what run-time options your site has as default, the easiest thing to do is to include a CEEOPTS DD statement in your run JCL.
//CEEOPTS DD *
RPTOPTS(ON)
This will list out all the options used for your "Enclave" (your run environment) and indicate where each option is sourced from.
If, in the OPTION column, you see NODEBUG, then COBOL debugging is turned off by default. To turn it on for a particular run:
//CEEOPTS DD *
DEBUG
This will allow all the D-labelled debugging lines and the debugging DECLARATIVES to execute.
This will do what you want, but no-one will allow a program with debugging on into Production, so you can't use it for what you want.
In order of preference, I advise error-numbers (and testing), automation, hand-coded procedure-name literals.
IBM fully documents all its products, and you can find the documentation (Language Reference and Programming Guide amongst others) for Enterprise COBOL V4.2 and also Language Environment (several) for your release of z/OS.
One final point. Don't use GO TO to "break out" of your normal processing flow. Use PERFORM. Even when, logically, the PERFORM cannot return. Using GO TO will turn off compiler optimisation for paragraphs/SECTIONs containing the GO TO which can easily cause a noticeable impact on execution. This is the reverse of the advice from before IBM COBOL ensured that the state of PERFORMed paragraphs/SECTIONs is not preserved between CALLs. At that time the correct advice was to use GO TO. It is no longer the correct advice.
As you have the pseudo-code "something bad happened here" I assume an exception. In this case the standard (COBOL 2002, COBOL 2014) function EXCEPTION-LOCATION may help (although the actual string is implementor-defined I assume the paragraph may be in there [GnuCOBOL for example has the format: program-id; paragraph [or paragraph OF section or section, depending on your program]; source-line]).
If your COBOL compiler provides this information in this function and there is no exception in the offending part already: create one via subtract 1 from unsigned-var or similar.
As Bill already said (or implied): this is a question where the actual COBOL compiler used will be the most important part if you must have the names in as identifier and as label or not.
Edit (after the actual COBOL compiler is known):
IBM MVS Enterprise COBOL doesn't have the EXCEPTION-LOCATION function. Therefore I see only one built-in solution:
DECLARATIVES.
debug-declaratives SECTION.
USE FOR DEBUGGING ON ALL PROCEDURES.
debug-par.
MOVE debug-name TO current-procedure.
END DECLARATIVES.
But as this is only active if your program runs in debugging-mode (which may causes a lot of debugging messages to occur) I don't suggest to actual use this.
Try to use an Editor providing macros (or run a shell script on your actual source) to create the source you pass to the compiler afterwards.

Display a Paragraph N times in COBOL

I am trying to call a paragraph N times using an online compiler which is OpenCOBOL v1.1.0 This is what I am doing :
IDENTIFICATION DIVISION.
PROGRAM-ID. PerformNTimes.
PROCEDURE DIVISION.
PERFORM 3 TIMES
DISPLAY 'IN A-PARA'
END-PERFORM
PERFORM B-PARA 3 TIMES.
STOP RUN.
B-PARA.
DISPLAY 'IN B-PARA'
Why it is not calling B-PARA?
It will probably be much more convenient for you to get your own compiler. OpenCOBOL is now known as GnuCOBOL, and is available, in more up-to-date versions, from SourceForge.Net.
Your example may not be compiling. You don't show a final full-stop/period after the DISPLAY in B-PARA.
There's full support for the product and assistance with COBOL in the discussion groups at the GnuCOBOL area: https://sourceforge.net/p/open-cobol/discussion/?source=navbar
Finally, I solved it. The point is each line should end with CRLF. Added a period after the DISPLAY in B-PARA and ended each line with CRLF. You can refer here to see how you can achieve this.

Getting started with OpenCOBOL! ("Hello world!")

I'm trying to make a very simple COBOL program. I've gotten my directory, configurations, etc. all set up, but when I go to compile it I get this error:
sampleCOBOL.cbl: In paragraph 'Main-Paragraph' :
sampleCOBOL.cbl:9: Error: syntax error, unexpected "end of file"
("sampleCOBOL.cbl" is my file name)
This is what my file contains:
Identification Division.
Program-ID. sampleCOBOL.
Data Division.
Procedure Division.
Main-Paragraph.
Display "Hello World!"
Stop Run.
I know that the error is occurring on Line#9 ("Stop Run."). However, why?
There is support for GNU COBOL (formerly OpenCOBOL) at SourgeForge.
From there, here is answer for the same error message: https://sourceforge.net/p/open-cobol/discussion/109660/thread/cdfe04a5/#0996
You can have you COBOL program obey the traditional fixed-column starts/ends, our you can put this, >>SOURCE FORMAT IS FREE in line one, column 12 of your program. You can then code without reference to column numbers.
If using column numbers, columns 1-6 are not used for code, column seven is for the comment, debugging, or new-page marker, or, rarely, continuing a literal which cannot fit on the previous line.
Code then either starts in columns 8-11 (aka "area a") or columnn 12-71 ("area b").
You do not need a full-stop/period in the PROCEDURE DIVISION except to end the PROCEDURE DIVISION header, before a paragraph/SECTION name and before the end of the program. In the distant past, you used to need lots of full-stops/periods, but not needed for many years (although many still code them).
Seeing your comment on the other answer and NealB's comment on your question, if you scroll down the linked-to discussion:
I have used Notepad++ for a lot of my own coding. You can set the EOL
to use UNIX instead of windows or UTF encoding. This will also resolve
EOF issues. Also, you will need to ensure you set "Use Spaces" when
tabbing. cobc has an issue when tabs are used from windows editors.
Putting that together, you are using Windows, tabs, and a version of OpenCOBOL which doesn't like tabs in source. You have two things to do directly to get it working, and you may want to get the latest version of GNU COBOL when it is convenient for you.
I suggest you go here, http://sourceforge.net/p/open-cobol/discussion/2526793/. Join, if you don't have a SourceForge account, or login if you do, and post in Help getting started. There are people there using Windows (which I don't) who should be able to help. The reason for login/join is that otherwise you will wait hours for your question to be "moderated" first, and you'll appear as Annonymous.
Figured out what was wrong. I had an extra line in between "Identification Division" and "Program-ID."
I have no idea how I missed that.
Boy, do I feel stupid.
The I of IDENTIFICATION must be at the column 8 ( 7 spaces before ).
---- sampleCOBOL.cob -------------------------
* Sample COBOL program
IDENTIFICATION DIVISION.
PROGRAM-ID. sampleCOBOL.
PROCEDURE DIVISION.
DISPLAY "Hello World!".
STOP RUN.
----------------------------------------
I faced the same problem recently when I just started learning COBOL. The point is each line should end with CRLF. You can refer here to see how you can achieve this.

Resources