Here's the whole shootin' match...
 
#!/usr/local/bin/perl -wT
# ----------------------------------------------------------------------
my $debug = 0;
my @database_dirs =
  (
   "/home/state/dof/fire/",
   "/home/state/dof/fire/"
  );
my @template_dirs =
  (
   "/home/state/dof/fire/",
   "/home/state/dof/fire/sit-rep-daily.shtml"
  );
# ----------------------------------------------------------------------
use File::Basename;
use strict;
my $is_cgi = ! @ARGV;
$is_cgi = 1;
my $data;         # Data file, relative to @database_dirs
my $template;     # Template, relative to @template_dirs
my $from;         # First record number, starting at 1
my $count;        # Number of records to display, 0 == all
my $match;        # Regular expression
my $mcol;         # Match columns, starting from 1
if ($is_cgi) {
  use CGI qw(param header);
  use CGI::Carp qw(fatalsToBrowser);
###########################################################################
# Get parameters
###########################################################################
  my $d     = param('data');
  my $t     = param('template');
  $from     = param('from') || 2;
  $count    = param('count') || 1;
  $match    = param('match');
  $mcol     = param('mcol') || 1;
  defined $d or usage("Input data file was not given");
  defined $t or usage("HTML template file was not given");
  $d =~ m|^/*(\w[\w\.\-]*)$| or usage("Not a valid file name $d");
  $d = $1;
  $t =~ m|^/*(\w[\w\.\-]*)$| or usage("Not a valid file name $t");
  $t = $1;
  foreach my $database_dir (@database_dirs) {
    if (-f "$database_dir/$d") {
      $data = "$database_dir/$d";
      last;
    }
  }
  foreach my $template_dir (@template_dirs) {
    if (-f "$template_dir/$t") {
      $template = "$template_dir/$t";
      last;
    }
  }
  defined $data or usage("File not found $data");
  defined $template or usage("File not found $template");
  $ENV{'PATH_INFO'} and usage("This new script is configured differently");
  print header();
} else {
  my $outfile = pop @ARGV;
  $outfile or usage("You have to specify an out file");
  $outfile =~ /^(\w[\w\.\-]*)$/ or usage("Out file not defined.");
  $outfile = $1;
  my %param = map {(split('=', $_, 2))} @ARGV;
  map {print "==== option $_ = $param{$_}<br>\n"} keys %param if $debug;
  # We get the parameters
  $data     = $param{'data'};
  $template = $param{'template'};
  $from     = $param{'from'} || 2;
  $count    = $param{'count'} || 1;
  $match    = $param{'match'};
  $mcol     = $param{'mcol'} || 1;
  defined $data or usage("CSV file not defined.");
  defined $template or usage("HTML template not defined.");
  open(STDOUT,">$outfile")
    or usage("Can't redirect STDOUT to file $outfile - $!");
}
$from  =~ /^\d+$/ or usage("'from' has to be a number");
$count =~ /^\d+$/ or usage("'count' has to be a number");
if (defined $match) {
  $match =~ s/^\s+//;
  $match =~ s/\s+$//;
  $mcol =~ /^\d+$/ or usage("Column has has to be a number: $mcol");
}

###########################################################################
#  Open HTML Template and Execute it
###########################################################################
open(DB, $data)
  or usage("Can't open file \"$data\": $!");
my @records;
my $i = 1;
while (<DB>) {
  my $record = parse_line($_);
  if (defined $match and $match) {
    print "MATCH $record->{$mcol} $mcol $match<br>\n" if $debug;
    next unless exists $record->{$mcol};
    next unless $record->{$mcol} =~ m{$match}oi;
  }
  print "ITERATE i = $i, from = $from, count = $count<br>\n" if $debug;
  next if $i++ < $from;
  last if $count and ($i > ($from + $count));
  push(@records, $record);
}
close DB;

open(TEMPLATE, $template)
  or usage("Can't open file \"$template\": $!");
do_page(join('', <TEMPLATE>));
close TEMPLATE;
close(STDOUT) unless $is_cgi;

###########################################################################
#  Substitution
###########################################################################
sub do_page {
  my $page = shift;
  foreach (split(m|(<repeat>.*?</repeat>)|si, $page)) {
    if (m|<repeat>(.*?)</repeat>|si) {
      print "**** start repeat<br>\n" if $debug;
      do_repeat($1);
      print "**** end repeat<br>\n" if $debug;
    } else {
      print "**** start text<br>\n" if $debug;
      print;
      print "**** end text<br>\n" if $debug;
    }
  }
}
sub do_repeat {
  my $repeat = shift;
  my $text = '';
  my @parts = split(/<next>/i, $repeat);
  while (@records) {
    print "** start record<br>\n" if $debug;
    foreach my $p (@parts) {
      last unless @records;     # FIXME: use or not????
      my $record = shift @records;
      my $part = $p;     # Copy so can change
      $part =~ s/\$arg([0-9]{1,3})/$record->{$1} || ''/ge;
      print "* start part<br>\n" if $debug;
      print $part;
      print "* end part<br>\n" if $debug;
    }
    print "** end record<br>\n" if $debug;
  }
}
###########################################################################
#  Parse one line
###########################################################################
sub parse_line {
  my $line = shift;
  chomp($line);
  print "LINE: $line<br>\n" if $debug;
  my %record;
  my $entry;
  my $i = 1;      # First index
  while ($line) {
    if ($line =~
        s {                     
           ^\"                  
           ((?:[^\"]|\"\")*)    
           \"                   
           (?:,|$)              
          } {}x) {              
      $entry = $1;
    } elsif ($line =~
             s {                
         ^               
         (.*?)           
         (?:,|$)         
               } {}x) {         
      $entry = $1;
    } else {
      die "Can't parse the line $line";
    }
    $entry =~ s/\"\"/\"/g;
    $record{$i++} = $entry;
  }
  return \%record;
}

 
Thanks again....

James Edward Gray II <[EMAIL PROTECTED]> wrote:On Feb 5, 2004, at 11:56 AM, Gregg 
O'Donnell wrote:

> Good follow-up, and here's a snippet:

Just FYI, there are multiple CSV parsing modules on the CPAN. I use 
Text::CSV_XS personally.

> sub parse_line {
> my $line = shift;
> chomp($line);
> print "LINE: $line
\n" if $debug;
> my %record;
> my $entry;
> my $i = 1; # First index
> while ($line) {
> if ($line =~
> s {
> ^\"
> ((?:[^\"]|\"\")*)
> \"
> (?:,|$)
> } {}x) {

" is not a special character, in a regular expression, so save your 
eyes and drop the \s. ;)

> $entry = $1;
> } elsif ($line =~
> s {
> ^
> (.*?)
> (?:,|$)
> } {}x) {
> $entry = $1;
> } else {
> die "Can't parse the line $line";
> }
> $entry =~ s/\"\"/\"/g;

This line is out of place, isn't it? It's only needed if the field was 
quoted and should be moved inside the if.

> $record{$i++} = $entry;

You can eliminate the need for this line and the entry variable, if you 
store them when you find them.

Also, you're using a hash when you should be using an array. 
Numerically indexed data belongs in an array.

> }
> return \%record;
> }

Unfortunately, this sub doesn't really tell us about your problem. I 
see nothing wrong here. Does %record contain what you think it does on 
exit? You might try printing it to find out.

I suspect the original problem is in your output code somewhere.

James



---------------------------------
Do you Yahoo!?
Yahoo! Finance: Get your refund fast by filing online

Reply via email to