#!/bin/ksh#set -xv
# -----------------------------------------------------
# PCO Analyzer
# -----------------------------------------------------
# good context menu samples: http://s-yadav.github.io/contextMenu.html
# -----------------------------------------------------
function ltrim {
str=`echo $1 | sed 's/^ *//g'`
}
function rtrim {
str=`echo $1 | sed 's/ *$//g'`
}
function trim {
str=`echo $1 | sed -e 's/^ *//g' -e 's/ *$//g'`
}
tmp=$0.$$
trap "rm $tmp 2>/dev/null" 0 1 2 3 15
# -----------------------------------------------------
# MAIN
# -----------------------------------------------------
if [ $# -eq 0 ]
then
echo Error: pco file name needed.
exit 1
fi
pco="$PS_HOME/src/cbl/batch/"$1".pco"
if [ ! -f $pco ]
then
echo Error: $pco does not exist.
exit 1
fi
# extract statements; exclude comments
#grep -e '^[ \t]*.* DIVISION.' -e '^.......[AS].*\.' -e '^.*PERFORM ' -ie '^[ \t]*.*IF ' -ie '^[ \t]*.* ELSE[ \t]*$' -ie '^[ \t]*.*END-PERFORM' -ie 'UNTIL' -ie '^[ \t]*.*END-IF' -ie '^[ \t]*.*EXEC SQL INCLUDE' -ie '^[ \t]* INCLUDE .*.sql' $pco | grep -v '^[ \t]*.* [AS].*-EXIT.' | grep -v '^......\*' > $tmp
tmp=$pco
cat << HERE
<!DOCTYPE html>
<html>
<head>
<style>
h3 {text-align:center}
.srcecode { white-space: pre;font-family:Courier,Times,serif; }
.pretxt { white-space: pre;font-family:Courier,Times,serif; }
.data a, .data span, .data tr, .data td { white-space: pre;font-family:Courier,Times,serif; }
.dvsn { white-space: pre;font-family:Courier,Times,serif; }
.filler { white-space: pre;font-family:Courier,Times,serif; }
.para { white-space: pre;font-family:Courier; font-weight:bold; }
.prfm { white-space: pre;font-family:Courier; }
.ifs { white-space: pre;font-family:Courier; }
.exec { white-space: pre;font-family:Courier; }
.cr_lf { white-space: pre;font-family:Courier; display: none}
.sql { background-color:yellow;}
.obso { background-color:yellow;}
.cmnt { white-space: pre;font-family:Courier; color:green; font-weight:bold;}
#btnGroup {
position: fixed;
top: 10px; /* space between top of browser and annoying box */
left: 10px; /* space between top of browser and annoying box */
width: 100px;
height: 100px;
}
#procPad {
//border:2px solid;
position: fixed;
top: 50px; /* space between top of browser and box */
left: 10px; /* space between top of browser and box */
width: 50px;
height: 50px;
}
#PadBox { width: 400px; margin: 0 auto; overflow: auto; border: 1px solid #0f0; padding: 2px; text-align: justify; background: transparent; }
#bookMark {
position: fixed;
top: 380px; /* space between top of browser and annoying box */
left: 10px; /* space between top of browser and annoying box */
width: 100px;
height: 10px;
}
#bmBox {
position: fixed;
top: 400px; /* space between top of browser and box */
left: 10px; /* space between top of browser and box */
height:320px;
width:250px;
border:1px solid #ccc;
font:12px/16px Georgia, Garamond, Serif;
overflow:auto;"}
</style>
<script>
function btnInit()
{
document.getElementById("btnGroup").style.left=(screen.width-330)+"px";
document.getElementById("procPad").style.left=(screen.width-100-document.getElementById("pad").offsetWidth+35)+"px";
document.getElementById("bmBox").style.left=(screen.width-100-document.getElementById("bmBox").offsetWidth+35)+"px";
document.getElementById("bookMark").style.left=(screen.width-330)+"px";
if (typeof window.clipboardData == "undefined")
document.getElementById("btnCopy").value = "Select";
document.getElementById("btnCopy").disabled = false;
document.getElementById("pad").style.visibility = "hidden";
document.getElementById("btnHide").value="Pad";
//document.getElementById("box").contentEditable='true';
}
function procPin(proc)
{
var txt=document.getElementById("pad").value;
if (txt.length > 0) txt=txt+"\n";
txt=txt+proc;
document.getElementById("pad").value=txt;
document.getElementById("pad").style.visibility = "visible";
document.getElementById("btnCopy").disabled = false;
document.getElementById("btnHide").value="Hide";
}
function clearPad()
{
document.getElementById("pad").value="";
document.getElementById("btnCopy").disabled = true;
}
function hidePad()
{
x=document.getElementById("pad");
x.style.visibility = (x.style.visibility == "visible"?"hidden":"visible");
document.getElementById("btnHide").value = (x.style.visibility == "visible"?"Hide":"Pad");
}
function copyPad(text) {
var controlValue = document.getElementById("pad").value;
if (window.clipboardData)
window.clipboardData.setData("Text", controlValue);
else
document.getElementById("pad").select();
}
function foldCode(text) {
// show or hide code
if ( document.getElementsByClassName)
var elemArray = document.getElementsByClassName('filler');
else
var elemArray = document.querySelectorAll("." + 'filler');
for(var i = 0; i < elemArray.length; i++)
elemArray[i].style.display= (document.getElementById("btnFold").value == "Fold"?"none":"block");
document.getElementById("btnFold").value = (document.getElementById("btnFold").value == "Fold"?"Unfold":"Fold");
// show or hide comments
if ( document.getElementsByClassName)
var elemArray = document.getElementsByClassName('cmnt');
else
var elemArray = document.querySelectorAll("." + 'cmnt');
for(var i = 0; i < elemArray.length; i++)
elemArray[i].style.display= (document.getElementById("btnFold").value == "Fold"?"block":"none");
// show or hide cr_lf
if ( document.getElementsByClassName)
var elemArray = document.getElementsByClassName('cr_lf');
else
var elemArray = document.querySelectorAll("." + 'cr_lf');
for(var i = 0; i < elemArray.length; i++)
elemArray[i].style.display= (document.getElementById("btnFold").value == "Fold"?"none":"block");
}
function bmPara(proc){
document.getElementById("bmBox").innerHTML=
document.getElementById("bmBox").innerHTML+"<a href=\\"#"+proc+"\\" title=\\"Jump to "+proc+"\\">"+proc+"</a><br>";
}
</script>
</head>
<body onload="btnInit();clearPad();">
<h3> <a id="top">PCO Analyzer</a></h3>
<h4> PCO=$pco</h4>
<h4> 1. <a href="#flow">Code Flow</a></h4>
<h4> 2. <a href="#count">Paragraph Count</a></h4>
<h4> 3. <a href="#sql">SQL Copy Books</a></h4>
<hr>
<div id="btnGroup">
<table>
<tr>
<td><input id="btnBack" action="action" type="button" value="Back" onclick="history.go(-1);" /></td>
<td><input id="btnHide" action="action" type="button" value="Hide" onclick="hidePad();" /></td>
<td><input id="btnClear" action="action" type="button" value="Clear" onclick="clearPad();" /></td>
<td><input id="btnCopy" action="action" type="button" value="Copy" onclick="copyPad();" /></td>
<td><input id="btnFold" action="action" type="button" value="Fold" onclick="foldCode();" /></td>
</tr>
</table>
</div>
<div id="procPad">
<textarea id="pad" rows="19" cols="30" style="color: red; background-color: lightyellow; font-style:italic; font-weight:bold" onkeydown="document.getElementById('Copy').disabled = false;">
</textarea>
</div>
<div id="bookMark">Bookmarks:</div>
<div id="bmBox"></div>
HERE
nawk -v sq="'" '
# ---------------------------
# function replacing bind variable with actual value
# parameters: st=sql statement, bn=bind seq, bv=bind value
# ---------------------------
function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s }
function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
function trim(s) { return rtrim(ltrim(s)); }
# -----------------------------------------------------
# begin section
# -----------------------------------------------------
BEGIN {
#print "<div class=\"data\"><span>"
}
END {
#print "</span>"
#print "</div> "
print " "
print " "
#print "</body>"
#print "</html>"
}
# -----------------------------------------------------
# main section
# -----------------------------------------------------
{
# sanitize
gsub(/</,"\<",$0);
gsub(/>/,"\>",$0);
if (substr($0,7,1) == "*")
print "<span class=\"cmnt\" style=\"display:block;\">"$0"</span>"
else{
# remove comments in col 1-7
txt=substr($0,7);
# DIVISION
if ( $0 ~ / DIVISION./ ){
if ($0 ~/PROCEDURE /)
print "<b><a id=\"flow\">Flow</a> <a href=\"#top\">Top</a></b>";
print "<span class=\"dvsn\" style=\"display:block;\">"$0"</span>" ;
}
else if ( txt ~ /^[ \t]*[AS][0-9].*\./ && txt !~ /^[ \t]*[AS][0-9].*-EXIT[ \t]*\./)
{
# PARAGRAPH heading - w/o ending "."
sub(/\./," ",txt);
str=trim(txt);
#print " ";
print "<span class=\"cr_lf\"> </span>"
if (txt ~ /[ \t]*[AS][0-9].*-EXIT[ \t]*$/) {
print "<span class=\"filler\" style=\"display:block;\">"rtrim($0)"</span>"
}
else {
print "<span class=\"para\" style=\"display:block;\"><a id=\"" str "\">" rtrim($0) "</a> <a href=\"#P_" str "\">called by</a> <a href=\"#U_" str"\">Count</a> <a href=\"javascript:bmPara("sq str sq ");\">bookmark</a> <a href=\"javascript:procPin("sq str sq ");\">pin</a></span>"
}
}
else if (ltrim($0) ~ /PERFORM [AS]/ )
{
# PERFORM paragraph
str=rtrim($0);
for(i=1; i<=NF; ++i)
{
if (index($i,"PERFORM") > 0)
break;
}
i++;
para=$i
sub(/PERFORM /,"PERFORM <a id=\"P_"$i"\"><a href=\"#"$i"\">",str);
print "<span class=\"prfm\" style=\"display:block;\">"rtrim(str)"</a></a></span>";
}
else if (ltrim($0) ~ /EXEC SQL INCLUDE/ )
{
# sql copy books
#str=$0;
#
#cpy=$4;
#
#gsub(/\"/,"",cpy);
#
##sub(/INCLUDE/,"INCLUDE <span class=\"sql\">",str);
# sub(/INCLUDE/,"INCLUDE <span class=\"sql\"><a id=\"I_"cpy"\"><a href=\"#"cpy"\">",str);
#sub(/END-EXEC/,"</a></a></span>END-EXEC",str);
#print rtrim(str);
for(i=1; i<=NF; ++i)
{
if (index($i,"sql") > 0)
break;
}
cpy=$i
gsub(/\"/,"",cpy);
gsub(/\".*.sql\"/,"<span class=\"sql\"><a id=\"I_"cpy"\"><a href=\"#"cpy"\">&<called by</a></a></span>",$0);
print "<span class=\"exec\" style=\"display:block;\">"$0"</span>";
}
else if (ltrim($0) ~ /^INCLUDE/ )
{
# sql copy books
for(i=1; i<=NF; ++i)
{
if (index($i,"sql") > 0)
break;
}
cpy=$i
gsub(/\"/,"",cpy);
gsub(/\".*.sql\"/,"<span class=\"sql\"><a id=\"I_"cpy"\"><a href=\"#"cpy"\">&<called by</a></a></span>",$0);
print "<span class=\"exec\" style=\"display:block;\">"$0"</span>";
}
else if ( toupper(txt) ~ /^[ \t]*IF / || toupper(txt) ~ /^[ \t]*ELSE[ \t]*$/ || toupper(txt) ~ /^[ \t]*END-IF[ \t]*/){
# if-then-else
print "<span class=\"ifs\" style=\"display:block;\">"$0"</span>"
}
else if ( txt ~ /^[ \t]*EXIT[ \t]*\. /){
# EXIT statement
print "<span class=\"filler\" style=\"display:block;\">"$0"</span>"
}
else
{
len=length($0);
if ( len == 0 )
print "<span class=\"filler\" style=\"display:block;\"> </span>"
else
print "<span class=\"filler\" style=\"display:block;\">"$0"</span>"
}}
}' $tmp
if [ $? -ne 0 ]; then
exit 1
fi
# get paragraph count
print "<hr>"
print "<span class=\"pretxt\">"
print "<a id=\"count\"><b>Count</b></a> <a href=\"#top\">Top</a>"
print " "
grep -e '^[ \t]*[AS][0-9]' $tmp | grep -v '^[ \t]*[AS][0-9].*-EXIT' | sort > $0.$$
while read x
do
##
##for x in `grep '^[ \t]*[AS][0-9]' $tmp | tr '.' ' ' | sort`
##do
col7=`echo $x | cut -c7-7`
if [ '*' != $col7 ]; then
para=`echo $x "\c" | sed -e 's/^ *//' -e 's/ *$//' -e 's/ *\.$//'`
cnt=`grep "PERFORM $para" $tmp | egrep -c '^.{6} '`
href='<a href="#'$para'.">'
cpy2=$para'</a></a>'
printf "<a id=\"U_"$para"\"><a href=\"#%s\">%-40s:" $para $cpy2
if [ $cnt -eq 0 ]; then
printf "<span class=\"obso\">"
fi
printf "%d" $cnt
if [ $cnt -eq 0 ]; then
printf "</span>"
fi
printf "\n"
fi
##
##done
done < $0.$$
print "</span>"
if [ $? -ne 0 ]; then
exit 1
fi
### get sql copy books
echo "<hr>"
echo "<span class=\"pretxt\">"
print "<a id=\"sql\"><b>SQL Copy Books</b></a> <a href=\"#top\">Top</a>"
for x in `grep -e ' EXEC SQL INCLUDE ' -e '^[ \t]* INCLUDE ' $tmp | egrep '^.{6} ' | awk -F \" '{print $2}' | sort`
do
cpy=$x
echo " "
echo "<a id=\""$cpy"\">*********"$cpy"</a> <a href=\"#I_"$cpy"\">called by</a> <a href=""javascript:bmPara('"$cpy"');"">bookmark</a>"
cat $PS_HOME/src/sql/$cpy
done
echo "</span>"
echo " "
echo "</body>"
echo "</html>"
rm $0.$$