1#!/usr/bin/gawk -f
2# -*- tab-width: 4; indent-tabs-mode: t -*-
3#
4# This file is part of the LibreOffice project.
5#
6# This Source Code Form is subject to the terms of the Mozilla Public
7# License, v. 2.0. If a copy of the MPL was not distributed with this
8# file, You can obtain one at http://mozilla.org/MPL/2.0/.
9#
10
11# Create dependency information from the output of cl.exe's showInclude.  It
12# needs additional information - the output name to which to write, objfile
13# that depends on the includes, and the original file name.
14# For best results all arguments should be absolute paths.
15#
16# It also consolidates the file names to a canonical form, and filters out
17# duplicates.
18#
19# based on filter-showInclude.pl by Jan Holesovsky <kendy@suse.cz>
20
21BEGIN {
22    if (!depfile || !objectfile || !sourcefile) {
23        print "usage: filter-showIncludes.awk -vdepfile=depfile.d " \
24          "-vobjectfile=objfile.o -vsourcefile=source.cxx" > "/dev/stderr"
25        exit 1
26    }
27    tempfile = depfile ".tmp"
28    print objectfile " : \\\n " sourcefile " \\" > tempfile
29
30    showincludes_prefix = ENVIRON["SHOWINCLUDES_PREFIX"];
31    if (!showincludes_prefix) {
32        showincludes_prefix = "Note: including file:"
33    }
34
35    # to match especially drive letters in allowlist case insensitive
36    IGNORECASE = 1
37    allowlist = \
38        "^(" ENVIRON["SRCDIR"] "|" ENVIRON["BUILDDIR"] ")"
39    firstline = 1
40}
41
42{
43    sub(/\r$/, "")
44    sub(/^ */, "")
45    if (index($0, showincludes_prefix) == 1) {
46        $0 = substr($0, length(showincludes_prefix) + 1)
47        sub(/^ */, "")
48
49        # The output from MSVC may contain a carriage return character at the
50        # end of filenames, in which case the translation unit will depend on a
51        # non-existing header, resulting in constant rebuild of all files,
52        # prevent that.
53        sub(/
54/, "")
55
56        gsub(/\\/, "/")
57        gsub(/ /, "\\ ")
58        if ($0 ~ allowlist) { # filter out system headers
59            if (!($0 in incfiles)) {
60                incfiles[$0]
61                print " " $0 " \\" > tempfile
62            }
63        }
64    } else {
65        # because MSVC stupidly prints errors on stdout, it's
66        # necessary to forward everything that isn't matched by the pattern
67        # so users get to see them.
68        if (firstline) { # ignore the line that just prints name of sourcefile
69            firstline = 0
70        } else {
71            print $0 > "/dev/stderr"
72        }
73    }
74}
75
76END {
77    if (!tempfile) {
78        exit 1
79    }
80    print "" > tempfile
81
82    # fdo#40099 if header.h does not exist, it will simply be considered out of
83    # date and any targets that use it as a prerequisite will be updated,
84    # which avoid misery when the header is deliberately deleted and removed
85    # as an include
86    # see http://www.makelinux.net/make3/make3-CHP-8-SECT-3
87    for (file in incfiles) {
88        print file " :\n" > tempfile
89    }
90
91    close(tempfile)
92    movecmd = "mv " tempfile " " depfile
93    ret = system(movecmd)
94    if (ret) {
95        print "ERROR: " movecmd " FAILED with status " ret > "/dev/stderr"
96        exit ret
97    }
98}
99
100# vim: set noet sw=4 ts=4:
101