views:

543

answers:

2

I have a number of flags defined (by a header file far outside my control) that look something like this:

  *
  * OPTVAL field for IPV6_ADDR_PREFERENCES_FLAGS
  *
   01 IPV6-ADDR-PREFERENCES-FLAGS PIC X(4).
  *
  * IPV6_ADDR_PREFERENCES_FLAGS mappings
  *
   77 IPV6-PREFER-SRC-HOME        PIC X(4) VALUE X'00000001'.      
   77 IPV6-PREFER-SRC-COA         PIC X(4) VALUE X'00000002'.      
   77 IPV6-PREFER-SRC-TMP         PIC X(4) VALUE X'00000004'.      
   77 IPV6-PREFER-SRC-PUBLIC      PIC X(4) VALUE X'00000008'.      
   77 IPV6-PREFER-SRC-CGA         PIC X(4) VALUE X'00000010'.
   77 IPV6-PREFER-SRC-NONCGA      PIC X(4) VALUE X'00000020'.

I need to perform a binary OR on a few of these flags, and I'm wondering if there is an easy way to do this that I am not aware of. Is there a simple keyword or syntax that will cause my program to treat these flags as binary values and let me do my math, or is this header file just completely broken?

+3  A: 

I would consider this library poorly written. If you're going to write a low-level library for use by COBOL, you should pick data types that are easier for COBOL to manipulate. In this case, a COMP item representing a longword (S9(9) COMP) would be easier for COBOL to cope with.

Assuming you're OR-ing these values together to make a call to a lower-level library, you could just add them together to get the flag values. This works because each constant has a single bit set.

You could move the constants to a temporary redefines area, or take advantage of COBOL's lack of type safety and pass them to a sub program for the operation. The following would work on VMS COBOL:

IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLEOR.
DATA DIVISION.
WORKING-STORAGE SECTION.
*
* OPTVAL field for IPV6_ADDR_PREFERENCES_FLAGS
*
 01 IPV6-ADDR-PREFERENCES-FLAGS PIC X(4).
*
* IPV6_ADDR_PREFERENCES_FLAGS mappings
* 
 77 IPV6-PREFER-SRC-HOME        PIC X(4) VALUE X'00000001'.      
 77 IPV6-PREFER-SRC-COA         PIC X(4) VALUE X'00000002'.      
 77 IPV6-PREFER-SRC-TMP         PIC X(4) VALUE X'00000004'.      
 77 IPV6-PREFER-SRC-PUBLIC      PIC X(4) VALUE X'00000008'.      
 77 IPV6-PREFER-SRC-CGA         PIC X(4) VALUE X'00000010'.
 77 IPV6-PREFER-SRC-NONCGA      PIC X(4) VALUE X'00000020'.

PROCEDURE DIVISION.
1.
    CALL "BINARYOR" 
        USING IPV6-PREFER-SRC-HOME
              IPV6-PREFER-SRC-COA    
              IPV6-ADDR-PREFERENCES-FLAGS.
    CALL "BINARYOR" 
        USING IPV6-PREFER-SRC-PUBLIC
              IPV6-ADDR-PREFERENCES-FLAGS
              IPV6-ADDR-PREFERENCES-FLAGS.

    IF IPV6-ADDR-PREFERENCES-FLAGS NOT = X'0000000B'
        DISPLAY "Failure"
    END-IF.

END PROGRAM SAMPLEOR.

IDENTIFICATION DIVISION.
PROGRAM-ID. BINARYOR.

DATA DIVISION.
WORKING-STORAGE SECTION.

LINKAGE SECTION.
 01     ARG1        PIC S9(9) COMP.
 01     ARG2        PIC S9(9) COMP.
 01     RESULT      PIC S9(9) COMP.

PROCEDURE DIVISION USING ARG1 ARG2 RESULT.
1. 
    ADD ARG1 TO ARG2 GIVING RESULT.
END PROGRAM BINARYOR.

If this doesn't work, then you'll need to study your COBOL platform's representation of binary items to work out the correct types.

I've done plenty of (too much probably) lower level things in COBOL (decades ago). Usually, you can work it out. But at some point it becomes too hard and not worth the trouble. At that point it pays to call out to a language (like C) that is better suited to twiddling bits.

Dave Smith
A: 

Binary operation can be performed using the COMP. COMP fields in COBOL are supposed to hold the binary values. When we have caluclate or do operation using the binary COMP fields are most advisable in COBOL. COMP being the binary format can hold either half word or full word (i.e. length of 2 bytes or 4 bytes). Which is very similar to assembler defining variable in H or F which stands for half or full word which translates to 2 byte or 4 byte. So when the mathematical operation are performed it better to use the COMP and then later move to alphanumeric field.