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 |
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
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.
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.
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