ocdoc.cob usage guide

Author:Brian Tiffin
Date:30-Sep-2008
Rights:Copyright (c) 2008, Brian Tiffin. GNU FDL License.
Purpose:Extract usage document lines from COBOL sources. Using OpenCOBOL 1.1pr. OpenCOBOL is tasty.
Tectonics:cobc -x ocdoc.cob
Docgen:$ ./ocdoc ocdoc.cob ocdoc.rst ocdoc.html skin.css

Command line

ocdoc runs in two forms.

Without arguments, ocdoc will act as a pipe filter. Reading from standard in and writing the extract to standard out.

The ocdoc command also takes an input file, an extract filename, an optional result file (with optional stylesheet) and a verbosity option -v or a special -fixed flag (to force skipping sequence numbers). If a result file is given, ocdoc will automatically run an rst2html command using the SYSTEM service.

Due to an overly simplistic argument handler, you can only turn on verbosity or -fixed when using all four filenames.

Examples:

$ cat ocdoc.cob | ocdoc >ocdoc.rst
$ ./ocdoc ocdoc.cob ocdoc.rst
$ ./ocdoc ocdoc.cob ocdoc.rst ocdoc.html skin.css -fixed
...
Input  : ocdoc.cob
Output : ocdoc.rst
Command: rst2html --stylesheet=skin.css ocdoc.rst ocdoc.html

What is extracted

Source code

Download ocdoc.cob See ocdocseq.cob

identification division

identification division.
program-id. OCDOC.

environment division.
input-output section.
file-control.
    select standard-input assign to KEYBOARD.
    select standard-output assign to DISPLAY.

    select source-input
    assign to source-name
    organization is line sequential
    .
    select doc-output
    assign to doc-name
    organization is line sequential
    .

data division

data division.
file section.
fd standard-input.
   01 stdin-record      pic x(256).
fd standard-output.
   01 stdout-record     pic x(256).

fd source-input.
   01 source-record     pic x(256).
fd doc-output.
   01 doc-record        pic x(256).

working-storage section.
01 arguments            pic x(256).
01 source-name          pic x(256).
01 doc-name             pic x(256).
01 result-name          pic x(256).
01 style-name           pic x(256).
01 verbosity            pic x(9).
   88 verbose           values "-v" "--v" "-verbose" "--verbose".
   88 skipseqnum        values "-fix" "-fixed" "--fix" "--fixed".
01 usagehelp            pic x(6).
   88 helping           values "-h" "--h" "-help" "--help".
01 filter-flag          pic x value low-value.
   88 filtering         value high-value.

01 line-count           usage binary-long.
01 line-display         pic z(8)9.

Note the conditional test for end of here doc

01 trimmed              pic x(256).
   88 herestart         value "*><[".
   88 hereend           value "*><]".

01 hereflag             pic x value low-value.
   88 heredoc           value high-value.
   88 herenone          value low-value.

Note the here-record adds an ocdoc extract to lines that follow.

01 here-record.
   02 filler            pic x(5) value "*><* ".
   02 here-data         pic x(251).

01 seq-record.
   02 filler            pic x(7) value "       ".
   02 seq-data          pic x(249).

01 doc-buffer           pic x(256).
01 buffer-offset        pic 999 usage comp-5 value 1.
01 buffer-flag          pic x value low-value.
   88 buffer-empty      value low-value.
   88 buffered-output   value high-value.

01 counter              pic 999 usage comp-5.
01 len-of-comment       pic 999 usage comp-5.

01 first-part           pic x(8).
   88 special           values "*><*" "*><+".
   88 autodoc           value "*><*".
   88 autoappend        value "*><+".

01 rst-command          pic x(256).
01 result               usage binary-long.

procedure division

*> ***************************************************************
 procedure division.

Accept command line arguments. See if help requested.

accept arguments from command-line end-accept

move arguments to usagehelp
if helping
    display
        "$ ./ocdoc source markover [output [skin [--fixed]]]"
    end-display
    display "$ ./ocdoc" end-display
    display
        "    without arguments extracts stdin to stdout"
    end-display
    goback
end-if

Either run as filter or open given files. Two filenames will generate an extract. Three will run the extract through rst2html using an optional fourth filename as a stylesheet.

*> Determine if this is running as a filter
 if arguments not equal spaces
     unstring arguments delimited by all spaces
         into source-name doc-name
              result-name style-name
              verbosity
     end-unstring

     open input source-input
     open output doc-output
 else
     set filtering to true

     open input standard-input
     open output standard-output
 end-if

Initialize the output buffer, and line count.

set buffer-empty to true
move 1 to buffer-offset
move spaces to doc-record
move 0 to line-count

The read is either from file or stdin. Start with the first record.

*> filtering requires different reader loop
 if filtering
     read standard-input
         at end move high-values to stdin-record
     end-read
     move stdin-record to source-record
 else
     read source-input
         at end move high-values to source-record
     end-read
 end-if

The main loop starts here, having done a pre-read to start things off.

perform until source-record = high-values
    add 1 to line-count

Small wrinkle if processing fixed form with sequence numbers, as the heredoc end marker needs to be recognized but we still want the sequence numbers in the heredoc.

So files processed --fixed play some data shuffling games.

if skipseqnum
    if heredoc
        move source-record(7 : 248) to trimmed
        move source-record to seq-data
        move seq-record to source-record
    else
        move source-record(7 : 248) to source-record
        move source-record to trimmed
    end-if
else
    move function trim(source-record leading) to trimmed
end-if

First to check for here doc start and end, setting flag if trimmed conditional the heredoc start or heredoc end strings.

if herestart
    set heredoc to true
end-if

if hereend
    set herenone to true
end-if

Inside the loop, we skip over heredoc entries. If it is normal, than check for heredoc and include source lines that follow, by prepending the extract tag

if (not herestart) and (not hereend)
    if heredoc
        move source-record to here-data
        move here-record to trimmed
    end-if

Unstring the line, looking for special tags in the first part.

unstring trimmed delimited by all spaces
    into first-part
        count in counter
end-unstring

If special, we either buffer or append to buffer

evaluate true when special
    if autoappend and buffer-empty
        move spaces to doc-record
        move 1 to buffer-offset
    end-if

    if autodoc and buffered-output
        if filtering
            move doc-record to stdout-record
            write stdout-record end-write
        else
            write doc-record end-write
        end-if
        if verbose
            display
                function trim(doc-record trailing)
            end-display
        end-if
        move spaces to doc-record
        set buffer-empty to true
        move 1 to buffer-offset
    end-if

Skip over where the tag was found plus an extra space. Adding 2 skips over the assumed space after a special tag

add 2 to counter
compute len-of-comment =
    function length(trimmed) - counter
end-compute

if len-of-comment > 0
    move trimmed(counter : len-of-comment)
        to doc-buffer
else
    move spaces to doc-buffer
end-if

Buffer the line, either to position 1 or appending to last.

        string
            function trim(doc-buffer trailing)
                delimited by size
            into doc-record
            with pointer buffer-offset
            on overflow
                move line-count to line-display
                display
                    "*** truncation *** reading line "
                    line-display
                end-display
        end-string
        set buffered-output to true
    end-evaluate
end-if

Again, we either read the next record from file or stdin.

    if filtering
        read standard-input
            at end move high-values to stdin-record
        end-read
        move stdin-record to source-record
    else
        read source-input
            at end move high-values to source-record
        end-read
    end-if
end-perform

We may or may not end up with buffered data

if buffered-output
    set buffer-empty to true
    move 1 to buffer-offset
    if filtering
        move doc-record to stdout-record
        write stdout-record end-write
    else
        write doc-record end-write
    end-if
    if verbose
         display
            function trim(doc-record trailing)
         end-display
    end-if
    move spaces to doc-record
end-if

Close the OpenCOBOL files

if filtering
    close standard-output
    close standard-input
else
    close doc-output
    close source-input
end-if

if verbose
    display "Input  : " function trim(source-name) end-display
    display "Output : " function trim(doc-name) end-display
end-if

If we have a result file, use the SYSTEM service to generate an HTML file, possibly with stylesheet.

*> pass the extract through a markover, in this case ReST
 move spaces to rst-command
 if result-name not equal spaces
     if style-name equal spaces
         string
             "rst2html " delimited by size
             doc-name delimited by space
             " " delimited by size
             result-name delimited by space
             into rst-command
         end-string
     else
         string
             "rst2html --stylesheet=" delimited by size
             style-name delimited by space
             " " delimited by size
             doc-name delimited by space
             " " delimited by size
             result-name delimited by space
             into rst-command
         end-string
     end-if

     if verbose
         display
             "Command: "
             function trim(rst-command trailing)
         end-display
     end-if

     call "SYSTEM"
         using rst-command
         returning result
     end-call

     if result not equal zero
         display "HTML generate failed: " result end-display
     end-if
 end-if

And before you know it, we are done.

goback.

end program OCDOC.

Don't forget to visit http://opencobol.org

Cheers

Last edit: 03-Oct-2008