Reformatted.
[chise/xemacs-chise.git.1] / src / make-src-depend
1 : #-*- Perl -*-
2 # Copyright (C) 1998 Free Software Foundation, Inc.
3
4 # This file is part of XEmacs.
5 #
6 # XEmacs is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; either version 2, or (at your option) any
9 # later version.
10 #
11 # XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 # for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with XEmacs; see the file COPYING.  If not, write to
18 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA.
20
21 # Author: Martin Buchholz
22 eval 'exec perl -w -S $0 ${1+"$@"}'
23   if 0;
24
25 use strict;
26 my ($myName, $srcdir, %exists, %uses, %generated_header);
27
28 ($myName = $0) =~ s@.*/@@; my $usage ="
29 Usage: $myName
30
31 Generates Makefile dependencies for the XEmacs src directory.
32 The dependencies are written to stdout.\n";
33
34 die $usage if @ARGV;
35
36 ($srcdir = $0) =~ s@[^/]+$@@;
37 $srcdir = "." if $srcdir eq "";
38 chdir $srcdir or die "$srcdir: $!";
39
40 opendir SRCDIR, "." or die "$srcdir: $!";
41 for (grep (/\.[ch]$/, readdir (SRCDIR))) { $exists{$_} = 1; }
42 closedir SRCDIR;
43
44 for (qw (config.h sheap-adjust.h paths.h Emacs.ad.h)) {
45   $generated_header{$_} = 1;
46 }
47
48 # Although this is not technically true, it ought to be true,
49 # and makes the generated Makefile smaller.
50 $uses{'lisp.h'}{'config.h'} = 1;
51
52 for my $file (keys %exists) {
53   open (FILE, $file) or die "$file: $!";
54   undef $/; $_ = <FILE>;
55   RemoveComments ($_);
56   s/[ \t]+//g;
57   # Find include dependencies
58   for (/^\#include([^\n]+)/gm) {
59     if (m@^\"([A-Za-z0-9._-]+\.[ch])\"@) {
60       $uses{$file}{$1} = 1 if exists $exists{$1};
61     } elsif (m@<([A-Za-z0-9._-]+\.h)>@) {
62       $uses{$file}{$1} = 1 if exists $generated_header{$1};
63     } elsif (m@\"../lwlib/([A-Za-z0-9._-]+\.h)\"@) {
64       $uses{$file}{"\$(LWLIB_SRCDIR)/lwlib.h"} = 1;
65     }
66   }
67 }
68
69 # Make transitive closure of %uses
70 while (1) {
71   my $changedP = 0;
72   for my $x (keys %uses) {
73     for my $y (keys %{$uses{$x}}) {
74       for my $z (keys %{$uses{$y}}) {
75         if (! exists $uses{$x}{$z}) {
76           $uses{$x}{$z} = 1;
77           $changedP = 1;
78         }
79       }
80     }
81   }
82   last if !$changedP;
83 }
84
85 # Print file header
86 print
87 "## This file is automatically generated by \`$myName'.  Do not modify.
88
89 #if defined(USE_UNION_TYPE)
90 LISP_UNION_H=lisp-union.h
91 #else
92 LISP_UNION_H=lisp-disunion.h
93 #endif
94 ";
95
96 my @LISP_H = ('lisp.h', sort keys %{$uses{'lisp.h'}});
97 print "LISP_H=@{[grep (!/lisp-(dis)?union\.h/, @LISP_H)]} \$(LISP_UNION_H)\n";
98
99 sub PrintDeps {
100   my $file = shift;
101   my $ofile = $file; $ofile =~ s/c$/o/; print "$ofile: ";
102   if (exists $uses{$file}{'lisp.h'}) {
103     delete @{%{$uses{$file}}}{@LISP_H};
104     $uses{$file}{'$(LISP_H)'} = 1;
105   }
106   print "@{[sort keys %{$uses{$file}}]}\n";
107 }
108
109 sub PrintPatternDeps {
110   my ($pattern, $CPP_SYMBOL) = @_;
111   print "#if defined($CPP_SYMBOL)\n";
112   for my $file (sort grep (/$pattern/ && /\.c$/, keys %uses)) {
113     PrintDeps($file);
114     delete $uses{$file};
115   }
116   print "#endif\n";
117 }
118
119 PrintPatternDeps ('-msw\\.',   "HAVE_MS_WINDOWS");
120 PrintPatternDeps ('-x\\.',     "HAVE_X_WINDOWS");
121 PrintPatternDeps ('-tty\\.',   "HAVE_TTY");
122 PrintPatternDeps ('-gtk\\.',   "HAVE_GTK");
123 PrintPatternDeps ('^database', "HAVE_DATABASE");
124 PrintPatternDeps ('^mule',     "MULE");
125 PrintPatternDeps ('^(?:External|extw-)', "EXTERNAL_WIDGET");
126
127 for my $file (sort grep (/\.c$/, keys %uses)) { PrintDeps($file); }
128
129 # Surprisingly robust regexp to remove comments from arbitrary C code
130 sub RemoveComments {
131   $_[0] =~
132     s{ (
133         [^\"\'/]+ |
134         (?:\"[^\"\\]*(?:\\.[^\"\\]*)*\" [^\"\'/]*)+ |
135         (?:\'[^\'\\]*(?:\\.[^\'\\]*)*\' [^\"\'/]*)+
136        )
137        | / (?:
138             \*[^*]*\*+(?:[^/*][^*]*\*+)*/
139             |
140             /[^\n]*
141            )
142      }{defined $1 ? $1 : ""}gsxeo;
143 }