Scons for COBOL

Viewed 86

I want to create a builder in scons works with COBOL.

Here is a start:

import re

Import('env')

# Source:
# src/cpy/COPYBK1.cpy
# src/cpy/COPYBK2.cpy
# src/cpy/COPYBK3.cpy
# src/bat/PROG1.cbl
# src/bat/PROG2.cbl
# These commands would run:
# cobc -o lib/PROG1.so -Isrc/cpy src/cbl/PROG1.cbl
# cobc -o lib/PROG2.so -Isrc/cpy src/cbl/PROG2.cbl
#     +-.
#       +-SConstruct
#       +-PROG1.cbl
#       +-PROG1.so
#       | +-PROG1.cbl
#       | +-COPYBK1.cpy
#       | +-COPYBK2.cpy
#       +-PROG2.cbl
#       +-PROG2.so
#       | +-PROG2.cbl
#       | +-COPYBK1.cpy
#       | +-COPYBK3.cpy
#
# Also, PROG2 is called from PROG1 so lib/PROG2.so target should be automatically generated.
# PROG2 is dynamically loaded so it does not need to linked into PROG1 target.

"""
def getCalls(fullprogrampath):
    # This needs to be modified to support multiple lines.
    # This needs to be modified to support nested COPY.
    theregex = r'^......]\s*CALL\s*([A-Z0-9]*)\.$'
    calllist = []

    with open(fullprogrampath, 'r') as f:
        linenum = 0
        for line in f.readlines():
            linenum += 1
            line = line.rstrip()
            m = re.match(theregex, line, re.I)
            if m:
                calllist.append(m.group(1))

    return(calllist)
"""

def getCopyBooks(fullprogrampath):
    # This needs to be modified to support multiple lines.
    # This needs to be modified to support nested COPY.
    theregex = r'^...... \s*COPY\s*([A-Z0-9]*)\.$'
    copybooklist = []

    with open(fullprogrampath, 'r') as f:
        linenum = 0
        for line in f.readlines():
            linenum += 1
            line = line.rstrip()
            m = re.match(theregex, line, re.I)
            if m:
                copybooklist.append(m.group(1))

    return(copybooklist)

bld = Builder(action = 'cobc -o $TARGET -Icpy $SOURCE')
env.Append(BUILDERS = {'CobolProgram': bld})

env.CobolProgram('lib/PROG1.so', 'bat/PROG1.cbl')
env.Depends(target = 'lib/PROG1.so', dependency = getCopyBooks('bat/PROG1.cbl'))

env.CobolProgram('lib/PROG2.so', 'cbl/PROG2.cbl')
env.Depends(target = 'lib/PROG2.so', dependency = getCopyBooks('cbl/PROG2.cbl'))

That actually runs

here is what needs to be added:

  1. Cache the scan for copybooks so that we only scan for copybooks if the files have changed. Scons seems to do that for C files so it must be possible.
  2. Detect call statements and add targets. There is no analogy to this in C.

A. How do I do that?

B. Is there some sample builders I can look at that I can model off of?

I acknowledge that COBOL is difficult to scan and that it will be limited to how crazy the COBOL is formatted. it will be up to the developer of the COBOL to add Depends calls for their copybooks and call statements that are not detected.

1 Answers

You cannot reliably find the target of a COBOL call in the general case with a regex. There are COBOL grammars you could use to generate a parser to aid you in writing an application to figure out the CALLs and COPYs but it's a non-trivial exercise.

Consider...

01  Work-Areas.
    05  Program1     PIC X(008) Value Low-Values.
        88  Name-Validate       Value 'N8675309'.
        88  Addr-Validate       Value 'A2718281'.
        88  Date-Validate       Value 'D3141592'.

[...]

    Set Addr-Validate To True
    Call Program1 Using [...]
    Set Date-Validate To True
    Call Program1 Using [...]
    Move 'X' To Program1(1:1)
    Call Program1 Using [...]

...and note that the code isn't even pathological, like this...

    Identification Division.
    Program-ID. CRAIS.
    Data Division.
    Working-Storage Section.

    01                                                              C
   -                                                                O
   -                                                                N
   -                                                                S
   -                                                                T
   -                                                                A
   -                                                                N
   -                                                                T
   -                                                               S.
        05                                                          P
   -                                                                G
   -                                                                M
                                                                    P
   -                                                                I
   -                                                                C
                                                                    X
   -                                                                (
   -                                                                8
   -                                                                )
                                                                    V
   -                                                                A
   -                                                                L
   -                                                                U
   -                                                                E
                                                                   'B
   -                                                               'R
   -                                                               'A
   -                                                               'C
   -                                                              'A'
        .
    Procedure Division.
                                                                    C
   -                                                                A
   -                                                                L
   -                                                                L
                                                                    P
   -                                                                G
   -                                                                M
                                                                    G
   -                                                                O
   -                                                                B
   -                                                                A
   -                                                                C
   -                                                                K
        .

COBOL COPY statements can also be continued like the nasty CALL above.

Related