I am getting compilation error for the variable I have defined in working storage section. please help me
WORKING-STORAGE SECTION.
77 WS-FS1 PIC 9(02).
77 WS-FS2 PIC 9(02).
01 WS-EOF-SW PIC X(01) VALUE 'N'.
88-EOF-SW VALUE 'Y'.
S "88-EOF-SW" WAS INVALID. SCANNING WAS RESUMED AT THE NEXT AREA "A" //Error msg
ITEM, LEVEL-NUMBER, OR THE START OF THE //Error msg
88-NOT-EOF-SW VALUE 'N'.
S "88-NOT-EOF-SW" WAS INVALID. SCANNING WAS RESUMED AT THE NEXT AREA //Error msg
"A" ITEM, LEVEL-NUMBER, OR THE START OF //Error msg
PROCEDURE DIVISION.
OPEN INPUT INPUT-FILE.
OPEN OUTPUT OUTPUT-FILE.
PERFORM UNTIL EOF-SW
S "EOF-SW" WAS NOT DEFINED AS A DATA-NAME. THE STATEMENT WAS DISCARD //Error msg
ED.
READ INPUT-FILE
AT END MOVE 'Y' TO WS-EOF-SW
MOVE IN-ALL(3:3) TO OUT-SYM
MOVE IN-ALL(6:7) TO OUT-POL
MOVE IN-ALL(13:2) TO OUT-MOD
MOVE IN-ALL(15:2) TO OUT-MCO
MOVE IN-ALL(17:2) TO OUT-LOC
END-READ
88-EOF-SW VALUE 'Y'.
There isn't a level number. Variable declarations require a level number.
Related
I am facing a problem while debugging a COBOL program, When using animator and when a call is made to another COBOL program with a CALL ... USING statement.
After entering the sub program and pressing P (for Perform) E (for Exit). The animator asks "Perform Level = 1 Zoom to calling program ?", and on pressing Y(for Yes) Animator shows the message "Perform Level 1", and doesn't proceed to the the next line in the calling program (i.e, MAIN.COB) .
The only option available then is to Zoom all along which is not helping much during debugging.
Is there a runtime Switch or a Compiler option to make animator pass the control back to the calling program
Example:
This is the main program that iam debugging
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-STUDENT-ID PIC 9(4) VALUE 1000.
01 WS-STUDENT-NAME PIC A(15) VALUE 'Tim'.
PROCEDURE DIVISION.
CALL 'UTIL' USING WS-STUDENT-ID, WS-STUDENT-NAME.
DISPLAY 'Student Id : ' WS-STUDENT-ID
DISPLAY 'Student Name : ' WS-STUDENT-NAME
STOP RUN.
This is the called program, UTIL,
IDENTIFICATION DIVISION.
PROGRAM-ID. UTIL.
DATA DIVISION.
LINKAGE SECTION.
01 LS-STUDENT-ID PIC 9(4).
01 LS-STUDENT-NAME PIC A(15).
PROCEDURE DIVISION USING LS-STUDENT-ID, LS-STUDENT-NAME.
DISPLAY 'In Called Program'.
MOVE 1111 TO LS-STUDENT-ID.
EXIT PROGRAM.
So when iam debugging MAIN program, and pass control to UTIL subroutine (by Perform and Step ). when i try to return back to calling program MAIN, animator gives the message "Perform Level = 1 Zoom to calling program ? Y/N" - when i press Y is shows a message at lower left saying ""Perform Level = 1" and doesnt skip to the program MAIN
When we look at the Perform / Call stack ( by pressing P and V ) animator displays the below Stack view
Perform/Call Stack View-----------------------------------
Program Name Section Name
----------------------------------------------------------
UTIL.int No Section or Paragraph
---------------------------------------------------------
Zoon Scroll <so on... >
---------------------------------------------------------
As you can see, only the Sub module is visible in the stack. Whereas it should have been.
Perform/Call Stack View-----------------------------------
Program Name Section Name
----------------------------------------------------------
UTIL.int No Section or Paragraph
MAIN.int No Section or Paragraph
---------------------------------------------------------
Zoon Scroll <so on... >
---------------------------------------------------------
(i.e., The calling point from the MAIN.int should also be visible)
This is why i suspect it has something to do with some missing compilation option or Environment settings
123456*
IDENTIFICATION DIVISION.
PROGRAM-ID. "EVEN-OR-ODD".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Num-1 PIC 9(02).
02 Answer PIC XXXX.
PROCEDURE DIVISION.
GOBACK.
EVEN-OR-ODD.
IF FUNCTION REM(NUM-1, 2) = 0
COMPUTE ANSWER = "Even"
ELSE
COMPUTE ANSWER = "Odd"
END-IF
END PROGRAM EVEN-OR-ODD.
Its a simple even odd function. It should check if number is even return "even" else return "odd"
Can someone explain what's wrong ?
So much things a COBOL compiler would have told you...
GOBACK as first statement, so the rest would not be executed
the program misses a final period and a necessary/reasonable (that depends on the compiler) statement to end the program (END PROGRAM is only parsed for the compilation phase) - you likely want to move your GOBACK. to the end
COMPUTE does not set anything to alphanumeric, you likely want MOVE
there is no way to know what the program would have done, so possibly want DISPLAY instead of MOVE
NUM-1 is never set and has no initial VALUE - so it could theoretically even abend
I have written the following program, I am confused why when I compile the program I get an error saying that A-COL(1,1) is not a numeric value while displaying A-COL(1,1) gives me 1.
IDENTIFICATION DIVISION.
PROGRAM-ID. TEST1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 DIFF PIC 9(3).
01 ARRAY.
05 A-ROW OCCURS 99 TIMES.
10 A-COL OCCURS 2 TIMES.
15 TABLE-CONTENT PIC 9(3).
PROCEDURE DIVISION.
MOVE 1 TO A-COL(1,1).
MOVE 2 TO A-COL(2,1).
DISPLAY A-COL(1,1).
COMPUTE DIFF = A-COL(1,1) - A-COL(2,1).
DISPLAY DIFF.
STOP RUN.
Change the A-COL definition to
"10 A-COL PIC 9(3) OCCURS 2 TIMES."
and remove the TABLE-CONTENT.
Group variables are considered alphanumeric (X type) so cannot be used in a computation.
Alternatively you may do this - refer to the address location using the actual numeric field.
PROCEDURE DIVISION.
MOVE 1 TO TABLE-CONTENT(1,1).
MOVE 2 TO TABLE-CONTENT(2,1).
DISPLAY A-COL(1,1).
COMPUTE DIFF = TABLE-CONTENT(1,1) - TABLE-CONTENT(2,1).
DISPLAY DIFF.
Also you might want to make DIFF signed.
Additional Information
A-COL(1,1) displays "1" because it stores the data as "1xx" where x = space. That is not a numeric value. When you run the solutions here you will notice that display line produces "001".
Keep your WORKING-STORAGE structure the same. However, your data-elements are not A-COL, but THE-CONTENT. So use THE-CONTENT, not A-COL.
IDENTIFICATION DIVISION.
PROGRAM-ID. TEST1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 DIFF PIC S9(3).
01 ARRAY.
05 A-ROW
OCCURS 99 TIMES.
10 A-COL
OCCURS 2 TIMES.
15 TABLE-CONTENT PIC 9(3).
PROCEDURE DIVISION.
MOVE 1 TO TABLE-CONTENT ( 1 1 )
MOVE 2 TO TABLE-CONTENT ( 2 1 )
DISPLAY
">"
TABLE-CONTENT ( 1 1 )
"<"
COMPUTE DIFF = TABLE-CONTENT ( 1 1 )
- TABLE-CONTENT ( 2 1 )
DISPLAY
">"
DIFF
"<"
STOP RUN
.
Your structure is better, because it is easier to maintain. If you ever want to REDEFINES TABLE-CONTENT, you can, without changing the structure. Not so if you "complicate" the structure now.
Yes, if you MOVE a numeric literal to a group-item, an alpha-numeric MOVE is carried out, the result will be your literal left-justified and space-padded to the right, or truncated to the right, or just fitting, depending on the size of your literal.
Although conceptually you have "columns" in your table (COBOL doesn't have arrays, it has tables with OCCURS), be aware that you cannot access a column as a whole. In storage you have row-1-col-1, row-1-col-2, row-2-col-1, row-2-col-2 through to row-99-col-1, row-99-col-2.
Any arithmetic (ADD, SUBTRACT, MULTIPLY, DIVIDE and COMPUTE) can only use numeric fields or literals as source-data. It is not enough that a field contains "a number", it must be a numeric field.
The GIVING (of ADD, SUBTRACT, MULTIPLY and DIVIDE) can place the result in a non-numeric field of a particular type, a numeric-edited field. This is a field with a PICture clause containing numeric-editing PICture symbols.
Given the following code:
IDENTIFICATION DIVISION.
PROGRAM-ID. FABS.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM PIC 9 VALUE ZEROS.
01 ABSVAL PIC 99 VALUE ZEROS.
PROCEDURE DIVISION.
PROGRAM-BEGIN.
DISPLAY "This program returns the absolute value of a number.".
DISPLAY SPACE.
DISPLAY "Input value: " WITH NO ADVANCING.
ACCEPT NUM.
IF (NUM = -0) THEN
COMPUTE ABSVAL = 0
ELSE
IF (NUM > 0) THEN
COMPUTE ABSVAL = 0
ELSE
COMPUTE ABSVAL = ABSVAL * -1
END-IF
END-IF.
DISPLAY "|", NUM "| = ", ABSVAL.
PROGRAM-DONE.
STOP RUN.
Why is the output zero? Is there something wrong? And how do you make a signed/negative input?
Thinking of your task, rather than why you get zero, it is easy.
Let's assume you get a signed value with your ACCEPT.
01 value-from-accept PIC S9.
01 absolute-value-for-output PIC 9.
MOVE value-from-accept TO absolute-value-for-output
DISPLAY
"|"
value-from-accept
"| = "
absolute-value-for-output
You may think that something is wrong with the output from value-from-accept (depending on compiler) but you can always MOVE it to a numeric-edited field and DISPLAY that.
Tip: To reverse the sign of a signed field.
SUBTRACT field-to-reverse-sign
FROM ZERO
GIVING the-reversed-field
SUBTRACT is faster than MULTIPLY.
You have defined your field which is ACCEPTed as unsigned.
The first two "legs" of your nested-IF set ABSVAL to zero. The remaining leg takes the existing value of ABSVAL (from the VALUE ZEROS, so it is zero) and multiplies it by minus one. Getting -ve zero (possibly), but then storing it in an unsigned field. So ABSVAL will always be zero when you come to the DISPLAY.
You define a signed field by prefixing the PICture string with an S:
01 a-signed-field PIC S9(5).
Depending on your compiler, you can type a - when entering the data and it'll be held happily as a negative value in a signed field (which you have to define) or you have to code for it yourself.
after your correction above
I am not sure how you are testing it but to just to ensure that the values are stored correct you may want to have both the fields signed i.e. pic S9 or pic S99. Its possible that without the preceding S (sign) the variables are not really storing the negative sign regardless of what the screen is showing.
pls observe what results you get then
So, i'm work with C and OpenCobol, and, I whant to know if have an way to get the value of a internal cobol source...
for example (based on sample of this link):
http://www.opencobol.org/modules/bwiki/index.php?cmd=read&page=UserManual%2F2_3
---- say.cob ---------------------------
IDENTIFICATION DIVISION.
PROGRAM-ID. say.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TESTE PIC 9(9) VALUE ZEROS.
LINKAGE SECTION.
01 HELLO PIC X(6).
01 WORLD PIC X(6).
PROCEDURE DIVISION USING HELLO WORLD.
MOVE 456 TO TESTE.
DISPLAY TESTE.
DISPLAY HELLO WORLD.
*> RETURN TESTE. ??????
EXIT PROGRAM.
----------------------------------------
And, the C code when I use is that:
---- hello.c ---------------------------
#include <stdio.h>
#include <libcob.h>
extern int say(char *hello, char *world);
int
main()
{
int ret;
char hello[6] = "Hello ";
char world[6] = "World!";
cob_init(0, NULL);
ret = say(hello, world); // return the 000000456 ??????????
// How to make this :(
return ret;
}
----------------------------------------
Or, have an whay to get the cobol variable, something like this:
// ... code ...
int value = cob_getvar(TESTE);
// ... code ...
Look at page 7-7 of the OpenCOBOL Programmers Guide. For the data that you want to pass back to your C program, add another argument and pass it by reference to the COBOL program. Declare your TESTE as binary to match the C declaration. You can also pass back the automatically-defined RETURN-CODE, if you like. So your COBOL would be something like this:
DATA DIVISION.
LINKAGE SECTION.
01 HELLO PIC X(6).
01 WORLD PIC X(6).
01 TESTE PIC S9(9) USAGE BINARY-LONG.
PROCEDURE DIVISION USING
BY VALUE HELLO
BY VALUE WORLD
BY REFERENCE TESTE.
0000-MAIN-ROUTINE.
MOVE 456 TO TESTE
MOVE 1 TO RETURN-CODE
GOBACK.
And in your calling program:
int teste;
int returnCode;
char hello[6] = "Hello ";
char world[6] = "World!";
cob_init(0, NULL);
returnCode = say(hello, world, &teste);
Alexandre;
OpenCOBOL 2.0 will have FUNCTION-ID allowing for things like
MOVE FUNCTION nextbigthing(args) TO cobol-working-store
Until it is released though, we are "limited" to CALL, ENTRY, PROGRAM-ID and the like.
For an example of some low level function pointer related things, take a look at
http://opencobol.add1tocobol.com/#what-stock-call-library-does-opencobol-offer
which includes a snippet for setting error handlers and exit procedures. Scan that with an eye on
PROCEDURE-POINTER
ENTRY
SET proc-ptr TO ENTRY "link-name"
CALL ... USING ... RETURNING
with the caveat, that this is one way. There are others. The ENTRY lines can be full on PROGRAM-ID subprograms, etc. Section 5 of the OpenCOBOL FAQ is rife with routines that pass data back and forth from other languages and link libraries.
Also, look to cob_field in libcob/common.h. The C code generated by CALL sets up an array of the COBOL fields of the arguments, along with the actual call frame, and these COBOL field structures can be accessed from C functions through cob_module.
errorproc.cob
>>SOURCE FORMAT IS FIXED
*****************************************************************
* OpenCOBOL demonstration
* Author: Brian Tiffin
* Date: 26-Jun-2008
* History:
* 03-Jul-2008
* Updated to compile warning free according to standards
* Purpose:
* CBL_ERROR_PROC and CBL_EXIT_PROC call example
* CBL_ERROR_PROC installs or removes run-time error procedures
* CBL_EXIT_PROC installs or removes exit handlers
* Also demonstrates the difference between Run time errors
* and raised exceptions. Divide by zero raises an
* exception, it does not cause a run time error.
* NB:
* Please be advised that this example uses the functional but
* now obsolete ENTRY verb. Compiling with -Wall will display
* a warning. No warning will occur using -std=MF
* Tectonics: cobc -x errorproc.cob
identification division.
program-id. error_exit_proc.
data division.
working-storage section.
* entry point handlers are procedure addresses
01 install-address usage is procedure-pointer.
01 install-flag pic 9 comp-x value 0.
01 status-code pic s9(9) comp-5.
* exit handler address and priority (prio is IGNORED with OC1.1)
01 install-params.
02 exit-addr usage is procedure-pointer.
02 handler-prio pic 999 comp-x.
* indexing variable for back scannning error message strings
01 ind pic s9(9) comp-5.
* work variable to demonstrate raising exception, not RTE
01 val pic 9.
* mocked up error procedure reentrancy control, global level
01 once pic 9 value 0.
88 been-here value 1.
* mocked up non-reentrant value
01 global-value pic 99 value 99.
* LOCAL-STORAGE SECTION comes into play for ERROR_PROCs that
* may themselves cause run-time errors, handling reentry.
local-storage section.
01 reenter-value pic 99 value 11.
* Linkage section for the error message argument passed to proc
* By definition, error messages are 325 alphanumeric
linkage section.
01 err-msg pic x(325).
* example of OpenCOBOL error and exit procedures
procedure division.
* Demonstrate problem installing procedure
* get address of WRONG handler. NOTE: Invalid address
set exit-addr to entry "nogo-proc".
* flag: 0 to install, 1 to remove
call "CBL_EXIT_PROC" using install-flag
install-params
returning status-code
end-call.
* status-code 0 on success, in this case expect error.
if status-code not = 0
display
"Intentional problem installing EXIT PROC"
", Status: " status-code
end-display
end-if.
* Demonstrate install of an exit handler
* get address of exit handler
set exit-addr to entry "exit-proc".
* flag: 0 to install, 1 to remove
call "CBL_EXIT_PROC" using install-flag
install-params
returning status-code
end-call.
* status-code 0 on success.
if status-code not = 0
display
"Problem installing EXIT PROC"
", Status: " status-code
end-display
stop run
end-if.
* Demonstrate installation of an error procedure
* get the procedure entry address
set install-address to entry "err-proc".
* install error procedure. install-flag 0 installs, 1 removes
call "CBL_ERROR_PROC" using install-flag
install-address
returning status-code
end-call.
* status-code is 0 on success.
if status-code not = 0
display "Error installing ERROR PROC" end-display
stop run
end-if.
* example of error that raises exception, not a run-time error
divide 10 by 0 giving val end-divide.
* val will be a junk value, use at own risk
divide 10 by 0 giving val
on size error display "DIVIDE BY ZERO Exception" end-display
end-divide.
* intentional run-time error
call "erroneous" end-call. *> ** Intentional error **
* won't get here. RTS error handler will stop run
display
"procedure division, following run-time error"
end-display.
display
"global-value: " global-value
", reenter-value: " reenter-value
end-display.
exit program.
*****************************************************************
*****************************************************************
* Programmer controlled Exit Procedure:
entry "exit-proc".
display
"**Custom EXIT HANDLER (will pause 3 and 0.5 seconds)**"
end-display.
* sleep for 3 seconds
call "C$SLEEP" using "3" end-call.
* demonstrate nanosleep; argument in billionth's of seconds
* Note: also demonstrates OpenCOBOL's compile time
* string catenation using ampersand;
* 500 million being one half second
call "CBL_OC_NANOSLEEP" using "500" & "000000" end-call.
exit program.
*****************************************************************
* Programmer controlled Error Procedure:
entry "err-proc" using err-msg.
display "**ENTER error procedure**" end-display.
* These lines are to demonstrate local and working storage
display
"global-value: " global-value
", reenter-value: " reenter-value
end-display.
* As reenter-value is local-storage
* the 77 will NOT display on rentry, while the global 66 will
move 66 to global-value.
move 77 to reenter-value.
* Process err-msg.
* Determine Length of error message, looking for null terminator
perform varying ind from 1 by 1
until (err-msg(ind:1) = x"00") or (ind = length of err-msg)
continue
end-perform.
display err-msg(1:ind) end-display.
* demonstrate trapping an error caused in error-proc
if not been-here then
set been-here to true
display "Cause error while inside error-proc" end-display
call "very-erroneous" end-call *> Intentional error
end-if.
* In OpenCOBOL 1.1, the return-code is local and does
* not influence further error handlers
*move 1 to return-code.
move 0 to return-code.
display "**error procedure EXIT**" end-display.
exit program.