3 package GenericPrepTemplate;
7 # use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
10 # @EXPORT= qw(&process_input);
22 $fn= '<command line>';
26 $fh->fdopen(fileno(STDIN),'r') or err("fdopen stdin: $!");
27 process_fh($fh,'<standard input>');
28 $fh->close or err("close stdin: $!\n");
30 for ($i=0; $i<@main::ARGV; $i++) {
31 $lno= '<arg#'.($i+1).'>';
32 $value= $main::ARGV[$i];
33 $fh= new IO::File $value,'r' or err("cannot open file \`$value': $!");
34 process_fh($fh,$value);
35 $fh->close or err("gpt: cannot close file \`$value': $!");
38 close STDOUT or die "gpt: close stdout: $!\n";
41 sub err ($) { die "gpt: $fn:$lno: $_[0]\n"; }
45 if (@oplist>1) { $substr.= $str; }
46 else { $expr.= $str; }
51 if (@oplist) { $substr.=$str; }
52 else { output($str); }
58 print DEBUG "E $fn:$lno:e\`$expr'\n";
61 eval $GenericPrepTemplate::expr;
64 chomp $@; err("error: $@");
66 print DEBUG "E $fn:$lno:v\`$value'\n";
70 sub process_input () {
71 my ($esc,$top,$want,$fh,$value,$wasyes);
73 print DEBUG "L $fn:$lno:",join('',@oplist),
74 ":`$l' e\`$expr' s\`$substr'\n";
75 if (@oplist & 1) { # scanning perl
76 if ($l =~ m/(.)\@\@/m || $l =~ m/^()\@\@/m) {
77 ($to,$op,$esc,$l) = ($`,$1,$&,$');
79 if ($op =~ m/[ 0-9a-zA-Z_\;\)\}?]/ || $op eq '') {
83 $expr.= $op unless $op =~ m/[?]/;
87 } elsif ($top eq '?') {
88 push @oplist, '?',':;'.!!$value;
89 } elsif ($top ne '-') {
96 } elsif ($op =~ m/[\(\{]/) {
97 if (@oplist>1) { $substr.= $esc; }
100 err("bad escape sequence $op\@\@ in perl part");
106 } else { # scanning text
107 if ($l =~ m/\@\@(.|\n)/) {
108 ($to,$op,$esc,$l) = ($`,$1,$&,$');
110 if ($op =~ m/[-< \$?]/) {
111 $substr.= $esc if @oplist;
113 } elsif ($op =~ m/[\)\}\;\:]/) {
114 err("unmatched closing \@\@$op") unless @oplist;
116 if ($want =~ y/({/)}/) {
118 err("found \@\@$op but wanted \@\@$want")
120 } elsif ($want =~ m/^([:;]+)(1?)$/) {
121 ($want,$wasyes)=($1,$2);
122 err("found \@\@$op where not expected (wanted ".
123 join(' or ', map { "\@\@$_" } split //, $want).")")
124 unless $op =~ m/^[$want]$/;
125 '?' eq pop @oplist or die;
127 local ($l) = ($substr);
128 local ($substr,$expr,$to,$op);
134 push @oplist, '?',';'.!$wasyes;
137 die "internal /$want/ /$op/";
140 # Just finished a substr.
142 $substrs[$substri]= $substr;
143 print DEBUG "S $fn:$lno:S$substri\`$substr'\n";
144 $expr.= ' GenericPrepTemplate::output(' if $op eq '}';
145 $expr.= " GenericPrepTemplate::process_i($substri) ";
146 $expr.= " );\n" if $op eq '}';
152 err("bad escape sequence \@\@$op in text part");
162 sub process_fh ($$) {
163 local ($fh,$fn) = @_;
164 local ($l,$lno, @oplist,$substr,$expr,$to,$op);
166 while (defined ($l= $fh->getline)) {
167 next if $l =~ m,^\#\! ?/\S+/gpt\b, && $.==1;
171 die "gpt: $fn: read error: $!" if $fh->error;
175 if (defined $outbuf) {
176 print DEBUG "O \`$outbuf'+\`$_[0]'\n";
179 print DEBUG "O w\`$_[0]'\n";
180 print STDOUT $_[0] or err("write stdout: $!");
186 local ($l,$fn,$lno) = ($substrs[$i], "$fn<sub#$i>", '');
187 local ($outbuf, @oplist,$substr,$expr,$to,$op);