Page 1 of 2

Occurs and redefines

PostPosted: Sun May 12, 2013 1:55 pm
by luckyboyroh
Hi friends ,

i am trying to check a string for value '&' and replace it using '&'. Please find the code below.
I am not able to identify where i m missing it. pls share your ideas guys.
Thanks.

01  WS-SUB1     PIC S9(04) COMP.
01  WS-SUB2     PIC S9(04) COMP.
01  WS-TEMP     PIC S9(04) COMP.

01 WS-VAR.
   05  WS-DESC        PIC X(30) VALUE 'AAA & BBB'.
   05  WS-DESC1  REDEFINES WS-DESC  OCCURS 30 TIMES
                      DEPENDING ON WS-SUB1.
       10 WS-CHAR     PIC X(01).

01 WS-VAR1.
   05  WS-DESC2  REDEFINES WS-DESC  OCCURS 100 TIMES
                      DEPENDING ON WS-SUB2.
       10 WS-CHAR1    PIC X(01).
PROCEDURE DIVISION.
0000-MAINLINE.
       MOVE 1 TO WS-SUB1
                       WS-SUB2

       PERFORM UNTIL WS-TEMP > 30
         IF WS-DESC1(WS-SUB1) = '&'       
             MOVE WS-DESC1(WS-SUB1) TO WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB1
                            WS-SUB2
             MOVE '&' TO  WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB2
             MOVE 'a' TO  WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB2
             MOVE 'm' TO  WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB2
             MOVE 'p' TO  WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB2
             MOVE ';' TO  WS-DESC2(WS-SUB2)
             ADD 1 TO WS-SUB2
          ELSE
            MOVE WS-DESC1(WS-SUB1) TO WS-DESC2(WS-SUB2)
            ADD 1 TO WS-SUB1
                          WS-SUB2
         END-IF
        END-PERFORM

Re: Occurs and redefines

PostPosted: Sun May 12, 2013 5:26 pm
by Robert Sample
1. You did not describe what problem you are having. Since we are not mind readers, that makes it hard to know how to proceed.

2. If you are changing a variable, you need an input variable and an output variable. Since you are doing everything in one variable, your original string is destroyed as soon as you find an ampersand.

Re: Occurs and redefines

PostPosted: Sun May 12, 2013 6:42 pm
by luckyboyroh
Sorry Robert. :oops:
I am getting compiler error .
cant we use redefines with occurs clause? or am i missing any syntax here :cry:
Compiler Error:
REDEFINES" subject "WS-DESC1" contained an "OCCURS DEPEND" clause
how should i change it ideally?

Re: Occurs and redefines

PostPosted: Sun May 12, 2013 7:15 pm
by Robert Sample
REDEFINES indicates you are taking a variable and overlaying the memory that variable uses with a different definition. When you have OCCURS DEPENDING, you are indicating that the length of the variable is not known until execution time. Since COBOL needs to determine the length of the REDEFINES at compile time, that causes the conflict and the error message.

Furthermore, if you want to use OCCURS DEPENDING ON, you MUST use a separate variable for the subscript. The code you have sets WS-SUB1 to 1 which means your variable WS-DESC has been changed from 'AAA & BBB' to 'A' -- not hardly the result you want.

What your code needs is something like this:
01 WS-INPUT-VAR.
   05  WS-INPUT        PIC X(30) VALUE 'AAA & BBB'.
   05  WS-DESC1  REDEFINES WS-INPUT  OCCURS 30 TIMES.
       10 WS-INPUT-CHAR     PIC X(01).

01 WS-OUTPUT-VAR1.
   05  05  WS-OUTPUT      PIC X(100).
    05  WS-DESC2  REDEFINES WS-OUTPUT  OCCURS 100 TIMES.
       10 WS-OUTPUT-CHAR    PIC X(01).

Re: Occurs and redefines

PostPosted: Sun May 12, 2013 10:01 pm
by luckyboyroh
thanks robert for detailed explanation.

But is it possible to acheive without using subscript? coz i need to scan each character in the input and need to check for '&' . if found need to replace.

For ex: AAA & BBB needs to be chnaged as AAA & BBB.

Could you pls show some snippet code. Really sorry for troubling again. Thanks .

Re: Occurs and redefines

PostPosted: Sun May 12, 2013 11:11 pm
by Robert Sample
You can do this with subscripts.
You can do this with indexes.
You can do this with reference modification and no indexes or subscripts:
 WORKING-STORAGE SECTION.
 77  WS-IN-LOC                   PIC 9(03).
 77  WS-OUT-LOC                  PIC 9(03).
 77  WS-IN-VAR                   PIC X(30).
 77  WS-OUT-VAR                  PIC X(100).
 PROCEDURE      DIVISION.
     MOVE 'AAA & BBB'            TO  WS-IN-VAR.
     MOVE 1                      TO  WS-OUT-LOC.
     PERFORM
         VARYING WS-IN-LOC FROM 1 BY 1
           UNTIL WS-IN-LOC > 30
         EVALUATE TRUE
         WHEN (WS-IN-VAR (WS-IN-LOC : 1) = '&')
             MOVE '&'        TO  WS-OUT-VAR (WS-OUT-LOC : 5)
             ADD 5               TO  WS-OUT-LOC
         WHEN OTHER
             MOVE WS-IN-VAR (WS-IN-LOC : 1)
                                 TO  WS-OUT-VAR (WS-OUT-LOC : 1)
             ADD 1               TO  WS-OUT-LOC
         END-EVALUATE
     END-PERFORM.
     DISPLAY ' INPUT: >' WS-IN-VAR '<'.
     DISPLAY 'OUTPUT: >' WS-OUT-VAR '<'.
produces output of
 INPUT: >AAA & BBB                     <
OUTPUT: >AAA &AMP; BBB                                                                                        <
The EVALUATE allows you to add other special characters and still make just one pass through the input variable.

Re: Occurs and redefines

PostPosted: Mon May 13, 2013 12:04 am
by luckyboyroh
Thanks Robert!!! It worked. and evaluate is best as i could add some more special character and check. Thanks Again.

Re: Occurs and redefines

PostPosted: Mon May 13, 2013 12:08 am
by luckyboyroh
i was just wondering how it could still be possible using subscripts. pls share wen u get time. thanks for ur time to respond to the query again. have a nice day

Re: Occurs and redefines

PostPosted: Mon May 13, 2013 1:51 am
by Robert Sample
 77  WS-IN-LOC                   PIC 9(03).
 77  WS-OUT-LOC                  PIC 9(03).
 01  WS-IN-VAR.
     05  WS-IN-CHAR              OCCURS 30
                                 PIC X(01).
 01  WS-OUT-VAR.
     05  WS-OUT-CHAR             OCCURS 100
                                 PIC X(01).
 PROCEDURE      DIVISION.
     MOVE 'AAA & BBB'            TO  WS-IN-VAR.
     MOVE 1                      TO  WS-OUT-LOC.
     PERFORM
         VARYING WS-IN-LOC FROM 1 BY 1
           UNTIL WS-IN-LOC > 30
         EVALUATE TRUE
         WHEN (WS-IN-CHAR (WS-IN-LOC) = '&')
             MOVE '&'            TO  WS-OUT-CHAR (WS-OUT-LOC)
             MOVE 'A'            TO  WS-OUT-CHAR (WS-OUT-LOC + 1)
             MOVE 'M'            TO  WS-OUT-CHAR (WS-OUT-LOC + 2)
             MOVE 'P'            TO  WS-OUT-CHAR (WS-OUT-LOC + 3)
             MOVE ';'            TO  WS-OUT-CHAR (WS-OUT-LOC + 4)
             ADD 5               TO  WS-OUT-LOC
         WHEN OTHER
             MOVE WS-IN-CHAR (WS-IN-LOC)
                                 TO  WS-OUT-CHAR (WS-OUT-LOC)
             ADD 1               TO  WS-OUT-LOC
         END-EVALUATE
     END-PERFORM.
     DISPLAY ' INPUT: >' WS-IN-VAR '<'.
     DISPLAY 'OUTPUT: >' WS-OUT-VAR '<'.

Re: Occurs and redefines

PostPosted: Mon May 13, 2013 5:38 am
by BillyBoyo
You used to be able to have REDEFINES with ODO, but it was an "IBM Extension" to COBOL, it was never part of the ANSI Standard, and it was dropped by IBM.

If you want to use ODO in a REDEFINES, you define the ODO in the LINKAGE SECTION and SET its address to the address of the data to be redefined.

ODO wasn't giving you any benefit in your original code, anyway.

You can use ODO for "substring" processing.