428
+ − 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
442
+ − 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
428
+ − 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) {
462
+ − 59 if (m@^\"([A-Za-z0-9._-]+\.[ch])\"@) {
428
+ − 60 $uses{$file}{$1} = 1 if exists $exists{$1};
442
+ − 61 } elsif (m@<([A-Za-z0-9._-]+\.h)>@) {
428
+ − 62 $uses{$file}{$1} = 1 if exists $generated_header{$1};
442
+ − 63 } elsif (m@\"../lwlib/([A-Za-z0-9._-]+\.h)\"@) {
428
+ − 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
442
+ − 87 "## This file is automatically generated by \`$myName'. Do not modify.
428
+ − 88
442
+ − 89 #if defined(USE_UNION_TYPE)
428
+ − 90 LISP_UNION_H=lisp-union.h
+ − 91 #else
+ − 92 LISP_UNION_H=lisp-disunion.h
+ − 93 #endif
+ − 94 ";
+ − 95
452
+ − 96 my @LISP_H = ('lisp.h', sort keys %{$uses{'lisp.h'}});
442
+ − 97 print "LISP_H=@{[grep (!/lisp-(dis)?union\.h/, @LISP_H)]} \$(LISP_UNION_H)\n";
428
+ − 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) = @_;
442
+ − 111 print "#if defined($CPP_SYMBOL)\n";
428
+ − 112 for my $file (sort grep (/$pattern/ && /\.c$/, keys %uses)) {
+ − 113 PrintDeps($file);
+ − 114 delete $uses{$file};
+ − 115 }
+ − 116 print "#endif\n";
+ − 117 }
+ − 118
442
+ − 119 PrintPatternDeps ('-msw\\.', "HAVE_MS_WINDOWS");
+ − 120 PrintPatternDeps ('-x\\.', "HAVE_X_WINDOWS");
+ − 121 PrintPatternDeps ('-tty\\.', "HAVE_TTY");
462
+ − 122 PrintPatternDeps ('-gtk\\.', "HAVE_GTK");
442
+ − 123 PrintPatternDeps ('^database', "HAVE_DATABASE");
+ − 124 PrintPatternDeps ('^mule', "MULE");
428
+ − 125 PrintPatternDeps ('^(?:External|extw-)', "EXTERNAL_WIDGET");
+ − 126
+ − 127 for my $file (sort grep (/\.c$/, keys %uses)) { PrintDeps($file); }
+ − 128
442
+ − 129 # Surprisingly robust regexp to remove comments from arbitrary C code
428
+ − 130 sub RemoveComments {
+ − 131 $_[0] =~
+ − 132 s{ (
+ − 133 [^\"\'/]+ |
+ − 134 (?:\"[^\"\\]*(?:\\.[^\"\\]*)*\" [^\"\'/]*)+ |
+ − 135 (?:\'[^\'\\]*(?:\\.[^\'\\]*)*\' [^\"\'/]*)+
+ − 136 )
+ − 137 | / (?:
+ − 138 \*[^*]*\*+(?:[^/*][^*]*\*+)*/
+ − 139 |
+ − 140 /[^\n]*
+ − 141 )
+ − 142 }{defined $1 ? $1 : ""}gsxeo;
+ − 143 }