# Revision History
# 03-10-14 ROW Added posted processing that covers ranges of version
#              descriptors in stds.htm and stds.txt
# 05-30-04 ROW Last previous edit. Exact changes unknown.
# 07-22-00 ROW Add referenced standards processing for opcode html files.
#
# This program processes a file in the @files list if:
#   1) there is no file of that name in t10-html\backups, or
#   2) the file in t10-html\backups is more than one day older
#      that the file in t10-html
#
# Processing an already processed file has no adverse effects
# unless the file in asc-num.htm, where two files are combined
# to produce the final result. Extra checking is applied to
# ensure that asc-num.htm is not processed twice.

# Favorite constants
#
use constant true  => 1;
use constant false => 0;

# Load the references setup for obsolete operation codes
# used by the PostProcessOpRefs subroutine.

require '001OpRefsInfo.pl';

# What I need to know about the array returned by stat

use constant stat_mtime => 9;

# 24 hours in seconds

use constant s24hours => 86400;

# Files to process
# Warning: asc-alph.txt MUST FOLLOW asc-alph.htm or the backup
#          function of this program will break.

@files = ( "asc-alph.htm", "asc-alph.txt", "asc-num.htm", "asc-num.txt",
           "op-alph.htm", "op-alph.txt", "op-num.htm", "op-num.txt",
           "stds.htm", "stds.txt" );

# Loop on files to process

foreach $file (@files)
  {
  @stuff = stat( $file );
  unless ( @bkstuff = stat ( "backups\\$file" ) ) { @bkstuff[stat_mtime] = 0; };
  $dt = @stuff[stat_mtime] - @bkstuff[stat_mtime];
  if ( $dt < s24hours )
    { print "Skipping   $file\n"; }
  else
    {
    print "Processing $file\n";
    if ( $file ne "asc-num.htm" )
      {
      ProcessFile( $file );
      }
    else
      {
      ProcessFile( $file, "asc-num.h00", $file );
      };
    if ( $file eq "asc-alph.txt" ) { PostProcessAscAlpha(); };
    if ( $file =~ /op\-(alph|num)\.htm/ ) { PostProcessOpRefs( $file ); };
    if ( $file eq "stds.htm" ) { PostProcessStdsHTML(); };
    if ( $file eq "stds.txt" ) { PostProcessStdsText(); };
    };
  };

sub ProcessFile
{
my @file_list = @_;
my ($out_file, $in_file, $backup, $line, @output);
use File::Copy;

# Setup output file and list of files to process

$out_file = shift @file_list;
if ( $#file_list == -1 )
  { push @file_list, $out_file;
  }
else
  { if ( FileRepeat( $out_file, @file_list ) ) { return; };
  };

# Process list of files

while ( $in_file = shift @file_list )
  {
  $backup = "backups\\" . $in_file;    # Make a backup copy
  copy( $in_file, $backup );
  open( IN, "<$in_file" );
  while ( $line = <IN> )               # Strip leading blank lines
    {
    if ( $line ne "\n" )
      {
      push @output, $line;
      last;
      };
    };
  while ( $line = <IN> )               # Strip embedded blank lines
    {
    if ( $line =~ /^</ )               # that preceded a HTML operator line
      {
      while ( @output[$#output] eq "\n" ) { pop @output; };
      };
    push @output, $line;
    };
  while ( @output[$#output] eq "\n" )  # Strip trailing blank lines
    {
    pop @output;
    };
  close( IN );
  };

# Output the collected set of lines

open( OUT, ">$out_file" );
print OUT @output;
close( OUT );

return;
}

sub FileRepeat
{
# Generally, this program has no adverse effect if run repeatedly
# on the same file. But when more than one file is combined, repeating 
# the combination operation is undesireable. The code in this else 
# block checks for the presence of combined data in the output file, 
# and if there, skips processing.
#
my $otfl = shift @_;
my @fils = @_;
my ($infl, $tln, $ln);
for( my $i=0; $i<scalar(@fils); $i++ )
  {
  if ( @fils[$i] ne $otfl ) { $infl = @fils[$i]; };
  };
open( IN, "<$infl" );
while ( $tln = <IN> ) { if ( $tln ne "\n" ) { last; }; };
close( IN );
if ( open( IN, "<$otfl" ) )
  {
  while ( $ln = <IN> )
    {
    if ( $ln eq $tln )
      {
      print "  Repeat processing of multi-file entry skipped.\n";
      close( IN );
      return true;
      };
    };
  close( IN );
  };
return false;
}


sub PostProcessAscAlpha
{
# This routine compensates for a bug in the Paradox ASC-ASCQ
# Ask function used to develop the Alphabetic lists (in both
# asc-alph.htm and asc-alph.txt).
#
# The bug allows selection of ASC/ASCQ values that do not 
# have a description, which is not desireable. This routine
# removes the incorrectly selected ASC/ASCQ values from
# the two files.
#
# Since any addition of a new device type to the ASC/ASCQ
# Paradox database resurfaces the Ask function bug, it is
# easier to cleanup the mess in post-processing than it is
# to maintain the Paradox database correctly.
#
# Because of the update-in-place nature of this program
# the operations are performed by pulling the whole
# file into memory (with changes) and then overwriting
# the whole file.
# 
my (@output, $line, $skip);

# Post-process asc-alph.htm, removing all the blank
# descriptions; which Paradox has grouped together and
# surrounded with a unique <A ...> ... <\A> construct.

open( IN, "<asc-alph.htm" );
$skip=false;
@output = ();
while( $line = <IN> )
  {
  unless( $skip )
    {
    if( $line =~ /\<A NAME="ASC_ ">/ )
      {
      $skip = true;
      next;
      };
    push @output, $line;
    }
  else
    {
    if( $line =~ /\<\/A>/ ) { $skip = false; };
    };
  };
close( IN );
open( OUT, ">asc-alph.htm" );
print OUT @output;
close( OUT );

# Post-process asc-alph.txt, removing any line that
# contains only an ASC/ASCQ listing.

open( IN, "<asc-alph.txt" );
@output = ();
while( $line = <IN> )
  {
  if( $line eq "\n" )      { push @output, $line; };
  if( length($line) > 10 ) { push @output, $line; };
  };
close( IN );
open( OUT, ">asc-alph.txt" );
print OUT @output;
close( OUT );

return;
}

sub PostProcessStdsHTML()
{
# This routine fixes HTML Version Descriptors in which the name
# of the standard ends with />>>To>>> \d{1\2},[0-9A-F]{4}h/
# (i.e., ends with a range end descriptor for the named standard.
# The decimal \d range end is ignored.
# The hex range end is converted into part of an 'x to y' value
# in the code column.
#
# Because of the update-in-place nature of this program
# the HTML changes are made by pulling the whole file into 
# memory (with changes) and then overwriting the whole file.
#
my (@output, $line, $range);

open( IN, "<stds.htm" );
@output = ();
while( $line = <IN> )
  {
  if( $line =~ s/ \>\>\>To\>\>\> \d{1,2},([0-9A-F]{4}h)// )
    {
    $range = $1;
    push @output, $line;
    $line = <IN>;
    $line =~ s/([0-9A-F]{4}h)/$1 to $range/;
    };
  push @output, $line;
  };
close( IN );
open( OUT, ">stds.htm" );
print OUT @output;
close( OUT );

return;
}

sub PostProcessStdsText()
{
# This routine fixes text Version Descriptors in which the name
# of the standard ends with />>>To>>> \d{1\2},[0-9A-F]{4}h/
# (i.e., ends with a range end descriptor for the named standard.
# The decimal \d range end is ignored.
# The hex range end is converted into part of a two-line entry
# of the form:
#    begin to
#       +end+ original standard text minuse >>>To...
#
# Because of the update-in-place nature of this program
# the text changes are made by pulling the whole file into 
# memory (with changes) and then overwriting the whole file.
#
my (@output, $line, $end, $begin);

open( IN, "<stds.txt" );
@output = ();
while( $line = <IN> )
  {
  if( $line =~ s/ \>\>\>To\>\>\> \d{1,2},([0-9A-F]{4}h)// )
    {
    $end = $1;
    if( $line =~ s/^([0-9A-F]{4}h)// )
      {
      $begin = $1;
      push @output, $begin . " to \n";
      push @output, '   ' . $end . $line;
      };
    }
  else
    { push @output, $line;
    };
  };
close( IN );
open( OUT, ">stds.txt" );
print OUT @output;
close( OUT );

return;
}

sub PostProcessOpRefs($)
{
# This routine does the HTML dirty work for the obsolete
# operation codes where a referenced standard needs to be
# identified on the web site. These changes are available
# only in the HTML (not in the text versions) of the operation
# codes lists.
#
# Because of the update-in-place nature of this program
# the HTML changes are made by pulling the whole file into 
# memory (with changes) and then overwriting the whole file.
#
my $fl = @_[0];
my (@output, $line, $ref, $url);

open( IN, '<'.$file );
@output = ();
while( $line = <IN> )
  {
  if( $line =~ /]\n/ )
    # The lines needing fixing always end with a ]
    {
    $line =~ s/(\S) {1,51}\[/$1 \[/;   # Compress out excessive Paradox spaces
    foreach $ref (keys(%OpRefs))
      {
      $url = $OpRefs{$ref};
      $line =~ s/$ref/$url/;
      };
    };
  push @output, $line;
  };
close( IN );
open( OUT, '>'.$file );
print OUT @output;
close( OUT );

return;
}
