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 |
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
008500 identification division. 008600 program-id. OCDOC. 008700 008800 environment division. 008900 input-output section. 009000 file-control. 009100 select standard-input assign to KEYBOARD. 009200 select standard-output assign to DISPLAY. 009300 009400 select source-input 009500 assign to source-name 009600 organization is line sequential 009700 . 009800 select doc-output 009900 assign to doc-name 010000 organization is line sequential 010100 .
011100 data division. 011200 file section. 011300 fd standard-input. 011400 01 stdin-record pic x(256). 011500 fd standard-output. 011600 01 stdout-record pic x(256). 011700 011800 fd source-input. 011900 01 source-record pic x(256). 012000 fd doc-output. 012100 01 doc-record pic x(256). 012200 012300 working-storage section. 012400 01 arguments pic x(256). 012500 01 source-name pic x(256). 012600 01 doc-name pic x(256). 012700 01 result-name pic x(256). 012800 01 style-name pic x(256). 012900 01 verbosity pic x(9). 013000 88 verbose values "-v" "--v" "-verbose" "--verbose". 013100 88 skipseqnum values "-fix" "-fixed" "--fix" "--fixed". 013200 01 usagehelp pic x(6). 013300 88 helping values "-h" "--h" "-help" "--help". 013400 01 filter-flag pic x value low-value. 013500 88 filtering value high-value. 013600 013700 01 line-count usage binary-long. 013800 01 line-display pic z(8)9. 013900
Note the conditional test for end of here doc
014700 01 trimmed pic x(256). 014800 88 herestart value "*><[". 014900 88 hereend value "*><]". 015000 015100 01 hereflag pic x value low-value. 015200 88 heredoc value high-value. 015300 88 herenone value low-value. 015400
Note the here-record adds an ocdoc extract to lines that follow.
016300 01 here-record. 016400 02 filler pic x(5) value "*><* ". 016500 02 here-data pic x(251). 016600 016700 01 seq-record. 016800 02 filler pic x(7) value " ". 016900 02 seq-data pic x(249). 017000 017100 01 doc-buffer pic x(256). 017200 01 buffer-offset pic 999 usage comp-5 value 1. 017300 01 buffer-flag pic x value low-value. 017400 88 buffer-empty value low-value. 017500 88 buffered-output value high-value. 017600 017700 01 counter pic 999 usage comp-5. 017800 01 len-of-comment pic 999 usage comp-5. 017900 018000 01 first-part pic x(8). 018100 88 special values "*><*" "*><+". 018200 88 autodoc value "*><*". 018300 88 autoappend value "*><+". 018400 018500 01 rst-command pic x(256). 018600 01 result usage binary-long.
019600*> *************************************************************** 019700 procedure division. 019800
Accept command line arguments. See if help requested.
020600 accept arguments from command-line end-accept 020700 020800 move arguments to usagehelp 020900 if helping 021000 display 021100 "$ ./ocdoc source markover [output [skin]] --verbose" 021200 end-display 021300 display "$ ./ocdoc" end-display 021400 display " without arguments extracts stdin to stdout" 021500 end-display 021600 goback 021700 end-if 021800
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.
022900*> Determine if this is running as a filter 023000 if arguments not equal spaces 023100 unstring arguments delimited by all spaces 023200 into source-name doc-name 023300 result-name style-name 023400 verbosity 023500 end-unstring 023600 023700 open input source-input 023800 open output doc-output 023900 else 024000 set filtering to true 024100 024200 open input standard-input 024300 open output standard-output 024400 end-if 024500
Initialize the output buffer, and line count.
025300 set buffer-empty to true 025400 move 1 to buffer-offset 025500 move spaces to doc-record 025600 move 0 to line-count 025700
The read is either from file or stdin. Start with the first record.
026600*> filtering requires different reader loop 026700 if filtering 026800 read standard-input 026900 at end move high-values to stdin-record 027000 end-read 027100 move stdin-record to source-record 027200 else 027300 read source-input 027400 at end move high-values to source-record 027500 end-read 027600 end-if 027700
The main loop starts here, having done a pre-read to start things off.
028600 perform until source-record = high-values 028700 add 1 to line-count 028800
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.
030000 if skipseqnum 030100 if heredoc 030200 move source-record(7 : 248) to trimmed 030300 move source-record to seq-data 030400 move seq-record to source-record 030500 else 030600 move source-record(7 : 248) to source-record 030700 move source-record to trimmed 030800 end-if 030900 else 031000 move function trim(source-record leading) to trimmed 031100 end-if 031200
First to check for here doc start and end, setting flag if trimmed conditional the heredoc start or heredoc end strings.
032200 if herestart 032300 set heredoc to true 032400 end-if 032500 032600 if hereend 032700 set herenone to true 032800 end-if 032900
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
033900 if (not herestart) and (not hereend) 034000 if heredoc 034100 move source-record to here-data 034200 move here-record to trimmed 034300 end-if 034400
Unstring the line, looking for special tags in the first part.
035300 unstring trimmed delimited by all spaces 035400 into first-part 035500 count in counter 035600 end-unstring 035700
If special, we either buffer or append to buffer
036500 evaluate true when special 036600 if autoappend and buffer-empty 036700 move spaces to doc-record 036800 move 1 to buffer-offset 036900 end-if 037000 037100 if autodoc and buffered-output 037200 if filtering 037300 move doc-record to stdout-record 037400 write stdout-record end-write 037500 else 037600 write doc-record end-write 037700 end-if 037800 if verbose 037900 display 038000 function trim(doc-record trailing) 038100 end-display 038200 end-if 038300 move spaces to doc-record 038400 set buffer-empty to true 038500 move 1 to buffer-offset 038600 end-if 038700
Skip over where the tag was found plus an extra space. Adding 2 skips over the assumed space after a special tag
039600 add 2 to counter 039700 compute len-of-comment = 039800 function length(trimmed) - counter 039900 end-compute 040000 040100 if len-of-comment > 0 040200 move trimmed(counter : len-of-comment) 040300 to doc-buffer 040400 else 040500 move spaces to doc-buffer 040600 end-if 040700
Buffer the line, either to position 1 or appending to last.
041500 string 041600 function trim(doc-buffer trailing) 041700 delimited by size 041800 into doc-record 041900 with pointer buffer-offset 042000 on overflow 042100 move line-count to line-display 042200 display 042300 "*** truncation *** reading line " 042400 line-display 042500 end-display 042600 end-string 042700 set buffered-output to true 042800 end-evaluate 042900 end-if 043000
Again, we either read the next record from file or stdin.
043800 if filtering 043900 read standard-input 044000 at end move high-values to stdin-record 044100 end-read 044200 move stdin-record to source-record 044300 else 044400 read source-input 044500 at end move high-values to source-record 044600 end-read 044700 end-if 044800 end-perform 044900
We may or may not end up with buffered data
045700 if buffered-output 045800 set buffer-empty to true 045900 move 1 to buffer-offset 046000 if filtering 046100 move doc-record to stdout-record 046200 write stdout-record end-write 046300 else 046400 write doc-record end-write 046500 end-if 046600 if verbose 046700 display 046800 function trim(doc-record trailing) 046900 end-display 047000 end-if 047100 move spaces to doc-record 047200 end-if 047300
Close the OpenCOBOL files
048100 if filtering 048200 close standard-output 048300 close standard-input 048400 else 048500 close doc-output 048600 close source-input 048700 end-if 048800 048900 if verbose 049000 display "Input : " function trim(source-name) end-display 049100 display "Output : " function trim(doc-name) end-display 049200 end-if 049300
An if we have a result file, use the SYSTEM service to generate an HTML file, possibly with stylesheet.
050200*> pass the extract through a markover, in this case ReST 050300 move spaces to rst-command 050400 if result-name not equal spaces 050500 if style-name equal spaces 050600 string 050700 "rst2html " delimited by size 050800 doc-name delimited by space 050900 " " delimited by size 051000 result-name delimited by space 051100 into rst-command 051200 end-string 051300 else 051400 string 051500 "rst2html --stylesheet=" delimited by size 051600 style-name delimited by space 051700 " " delimited by size 051800 doc-name delimited by space 051900 " " delimited by size 052000 result-name delimited by space 052100 into rst-command 052200 end-string 052300 end-if 052400 052500 if verbose 052600 display 052700 "Command: " 052800 function trim(rst-command trailing) 052900 end-display 053000 end-if 053100 053200 call "SYSTEM" 053300 using rst-command 053400 returning result 053500 end-call 053600 053700 if result not equal zero 053800 display "HTML generate failed: " result end-display 053900 end-if 054000 end-if 054100
And before you know it, we are done.
054900 goback. 055000 055100 end program OCDOC.
Don't forget to visit http://opencobol.org
Cheers
Last edit: 03-Oct-2008