#!/usr/bin/perl
# skel.pl
# Prints the structure of a perl program by searching for flow control
# characters and code blocks without all the variable assignements.
# This is to see the overall structure of a program, what it does
# in general without all the distracting details.
#

$nocomment = 1;
$nolinenos = 1;
if (scalar(@ARGV) > 0) {
    while ($argv = shift(@ARGV)) {
        if ($argv =~ /^-h/i) {
            print " skel.pl: Reads STDIN and prints to STDOUT.\n";
            print " Usage:  cat filename | skel.pl -c -l | less\n";
            print "         or other similar pipes and redirects as needed.\n";
            print " skel.pl prints only the open/close code blocks indentified\n";
            print " by curly braces, and conditional statements identified by\n";
            print " parenthesis. This allows you to see the structure of a perl\n";
            print " program without all the distracting details. This is useful\n";
            print " for finding extra or missing open/close braces and paranthesis.\n";
            print " A CLI option -c will cause comments to be printed as well.\n";
            print " Comments are identified by pound sign.\n";
            print " skel.pl works reasonably well for C code but commanents can't\n";
            print " be displayed because this is a quick and dirty hack.\n";
            exit(0);
        } 
        if ($argv =~ /C/i) {
            $nocomment = 0;
        }
        if ($argv =~ /l/i) {
            $nolinenos = 0;
        }
    }
}


$lineno = 0;
while ($line = <STDIN>) {
    ++$lineno;

# egrep "if|while|for|else|'^#'|}"
# Use whitespace and open paren to get code and not comment lines that happen
# to contain those words.
    if (($line =~ /^if\s\(/) || ($line =~ /  if\s\(/) ||
       ($line =~ /^while\s\(/) || ($line =~ /  while\s\(/) ||
       ($line =~ /^for\s\(/) || ($line =~ /  for\s\(/) ||
       ($line =~ /^else/) || ($line =~ /  else/) ||
       ($line =~ /^do/) || ($line =~ /  do/) ||
       ($line =~ /^until/) || ($line =~ /  until/) ||
       ($line =~ /{/) || ($line =~ /}/) ||
       ($line =~ /^#/)) {
        if (($line =~ /^#/) && ($nocomment)) {
            next;
        }
# This excludes perl associative array assignements, like $hashvar{"key"} = 1.
# Just get the control structures, not all the variable assignements.
        if ((($line !~ /{\$.+}/) && ($line !~ /{\".+\"}/)) ||
            ($line =~ /{$|{\s.+$/))  {
            if ($nolinenos) {
                print $line;
            }
            else {
                printf("%6d %s", $lineno, $line);
            }
        }
    }
}


