1## -*- mode: Perl -*-
2##
3## Copyright (c) 2015, 2016, 2019 The University of Utah
4## All rights reserved.
5##
6## This file is distributed under the University of Illinois Open Source
7## License.  See the file COPYING for details.
8
9###############################################################################
10
11package pass_unifdef;
12
13use strict;
14use warnings;
15
16use POSIX;
17use File::Compare;
18use Cwd 'abs_path';
19
20use creduce_config qw(bindir libexecdir);
21use creduce_utils;
22
23my $unifdef;
24my $options = "-B -x 2";
25
26sub check_prereqs () {
27    my $path;
28    my $abs_bindir = abs_path(bindir);
29    if ((defined $abs_bindir) && ($FindBin::RealBin eq $abs_bindir)) {
30	# This script is in the installation directory.
31	# Use the installed `unifdef'.
32	$path = libexecdir . "/unifdef";
33    } else {
34	# Assume that this script is in the C-Reduce build tree.
35	# Use the `unifdef' that is also in the build tree.
36	$path = "$FindBin::Bin/../unifdef/unifdef";
37    }
38    if ((-e $path) && (-x $path)) {
39	$unifdef = $path;
40	return 1;
41    }
42    # Check Windows
43    $path = $path . ".exe";
44    if (($^O eq "MSWin32") && (-e $path) && (-x $path)) {
45	$unifdef = $path;
46	return 1;
47    }
48    return 0;
49}
50
51sub new ($$) {
52    my $index = -1;
53    return \$index;
54}
55
56sub advance ($$$) {
57    (my $cfile, my $arg, my $state) = @_;
58    my $index = ${$state};
59    $index++;
60    return \$index;
61}
62
63sub transform ($$$) {
64    (my $cfile, my $which, my $state) = @_;
65    my $index = ${$state};
66    my %defs;
67    open INF, "$unifdef -s $cfile 2>/dev/null |" or die;
68    while (my $line = <INF>) {
69	chomp $line;
70	$defs{$line} = 1;
71    }
72    close INF;
73    my @deflist = sort keys %defs;
74    my $tmpfile = File::Temp::tmpnam();
75
76    # remove constant ifs
77    if ($index == -1) {
78	my $cmd = "$unifdef -k -o $tmpfile $cfile >/dev/null 2>&1";
79	runit ($cmd);
80	$index++;
81	if (compare($cfile, $tmpfile) == 0) {
82	    goto AGAIN;
83        }
84	File::Copy::move($tmpfile, $cfile);
85	return ($OK, \$index);
86    }
87
88  AGAIN:
89    print "index = $index\n" if $DEBUG;
90    my $DU = (($index % 2) == 0) ? "-D" : "-U";
91    # my $DU = (($index % 2) == 0) ? "-U" : "-D";
92    my $n_index = int($index / 2);
93    return ($STOP, \$index) unless ($n_index < scalar(@deflist));
94    my $def = $deflist[$n_index];
95    my $cmd = "$unifdef $options $DU$def -o $tmpfile $cfile >/dev/null 2>&1";
96    print "$cmd\n" if $DEBUG;
97    my $res = runit ($cmd);
98    if (compare($cfile, $tmpfile) == 0) {
99	$index++;
100	print "AGAIN!\n" if $DEBUG;
101	goto AGAIN;
102    }
103    File::Copy::move($tmpfile, $cfile);
104    return ($OK, \$index);
105}
106
1071;
108