+}
+
+sub parse_progs($)
+{
+ my ($fh) = @_;
+
+ my %p = ();
+
+ print STDERR "Parsing header...\n";
+ $p{header} = parse_section $fh, DPROGRAMS_T, 0, undef, 1;
+
+ print STDERR "Parsing strings...\n";
+ $p{strings} = get_section $fh, $p{header}{ofs_strings}, $p{header}{numstrings};
+ $p{getstring} = sub
+ {
+ my ($startpos) = @_;
+ my $endpos = index $p{strings}, "\0", $startpos;
+ return substr $p{strings}, $startpos, $endpos - $startpos;
+ };
+
+ print STDERR "Parsing statements...\n";
+ $p{statements} = [parse_section $fh, DSTATEMENT_T, $p{header}{ofs_statements}, undef, $p{header}{numstatements}];
+
+ print STDERR "Fixing statements...\n";
+ for my $s(@{$p{statements}})
+ {
+ my $c = checkop $s->{op};
+
+ for(qw(a b c))
+ {
+ my $type = $c->{$_};
+ next
+ unless defined $type;
+
+ if($type eq 'inglobal' || $type eq 'inglobalfunc')
+ {
+ $s->{$_} &= 0xFFFF;
+ }
+ elsif($type eq 'inglobalvec')
+ {
+ $s->{$_} &= 0xFFFF;
+ }
+ elsif($type eq 'outglobal')
+ {
+ $s->{$_} &= 0xFFFF;
+ }
+ elsif($type eq 'outglobalvec')
+ {
+ $s->{$_} &= 0xFFFF;
+ }
+ }
+ }
+
+ print STDERR "Parsing globaldefs...\n";
+ $p{globaldefs} = [parse_section $fh, DDEF_T, $p{header}{ofs_globaldefs}, undef, $p{header}{numglobaldefs}];
+
+ print STDERR "Parsing fielddefs...\n";
+ $p{fielddefs} = [parse_section $fh, DDEF_T, $p{header}{ofs_fielddefs}, undef, $p{header}{numfielddefs}];
+
+ print STDERR "Parsing globals...\n";
+ $p{globals} = [parse_section $fh, DGLOBAL_T, $p{header}{ofs_globals}, undef, $p{header}{numglobals}];
+
+ print STDERR "Parsing functions...\n";
+ $p{functions} = [parse_section $fh, DFUNCTION_T, $p{header}{ofs_functions}, undef, $p{header}{numfunctions}];
+
+ print STDERR "Looking for error()...\n";
+ $p{error_func} = {};
+ for(@{$p{globaldefs}})
+ {
+ next
+ if $p{getstring}($_->{s_name}) ne 'error';
+ my $v = $p{globals}[$_->{ofs}]{v}{int};
+ next
+ if $v <= 0 || $v >= @{$p{functions}};
+ my $first = $p{functions}[$v]{first_statement};
+ next
+ if $first >= 0;
+ print STDERR "Detected error() at offset $_->{ofs} (builtin #@{[-$first]})\n";
+ $p{error_func}{$_->{ofs}} = 1;
+ }