This file is indexed.

/usr/share/pyshared/vamos/golem/inference.py is in undertaker 1.3b-1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#
#   golem - analyzes feature dependencies in Linux makefiles
#
# Copyright (C) 2012 Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
# Copyright (C) 2012 Reinhard Tartler <tartler@informatik.uni-erlangen.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import logging
import os

from vamos.golem.kbuild import determine_buildsystem_variables_in_directory, \
    apply_configuration, guess_source_for_target, call_linux_makefile

from vamos.selection import Selection
from vamos.golem.FileSet import FileSet, FileSetCache

def objects_in_dir(directory):
    """
    Returns object files and subdirectories in a specific directory

    @return tuple(set(object_files), set(subdirectories))
    """

    ret = (set(), set())

    for name in os.listdir(directory):
        name = os.path.join(directory, name)
        # is a directory
        if os.path.isdir(name):
            ret[1].add(name)
        elif name.endswith(".c"):
            name = name[:-len(".c")] + ".o"
            ret[0].add(name)
    return ret


class FileSymbolInferencer:
    def __init__(self, model, arch, subarch=None, subdir=""):
        """
        subdir is used to limit the subdirectories, on which the
        inference algorithm operates.

        """

        self.arch = arch
        self.subarch = subarch
        self.model = model

        # declaration only
        self.empty_selection = Selection()
        self.empty_fileset = None

        self.file_selections = {}

        # Directories that caused a recursion loop
        self.visited_dirs = set()
        self.directory_prefix = subdir

        self.file_set_cache = FileSetCache(arch=arch, subarch=subarch)


    def calculate(self):
        call_linux_makefile('allnoconfig', arch=self.arch, subarch=self.subarch)
        apply_configuration(arch=self.arch, subarch=self.subarch)

        self.empty_fileset = FileSet(self.empty_selection, arch=self.arch,
                                     subarch=self.subarch)

        for filename in self.empty_fileset.files:
            self.file_selections[filename] = None

        directories = self.empty_fileset.dirs
        directories.add("arch/%s" % self.arch)

        for directory in directories:
            symbol_slice = determine_buildsystem_variables_in_directory(directory)
            self.__calculate(directory, symbol_slice,
                             self.empty_selection,
                             self.empty_fileset)

        for objfile in self.file_selections:
            sourcefile = guess_source_for_target(objfile)
            if not sourcefile:
                logging.warning("Failed to guess source file for %s", objfile)
                sourcefile = objfile # makes these cases easier to identify
            if self.file_selections[objfile]:
                print "FILE_%s \"%s\"" % (sourcefile, self.file_selections[objfile])
            else:
                print "FILE_%s" % sourcefile

    def __subdirectory_is_worth_working_on(self, directory):
        """
        Determine if it is worth to work on a specific directory,
        or if all object files and all directories within are already visited
        """

        (objects, dirs) = objects_in_dir(directory)

        if not directory.startswith(self.directory_prefix):
            logging.info("Skipping %s, not in scope", directory)
            return False

        # Are all objects visited?
        for obj in objects:
            if not obj in self.file_selections:
                return True

        # Are all directories visited
        for dirname in dirs:
            if not dirname in self.visited_dirs:
                return True

        logging.info("Skipping %s, already processed", directory)
        return False


    def check_subdir(self, subdir, symbols):
        """
        @return a set of new symbols found in subdir
        """

        new_symbols = set()
        new_symbols.update(determine_buildsystem_variables_in_directory(subdir))
        new_symbols.update(symbols)

        # For tristate features also add the _MODULE
        # symbol
        to_be_removed = set()
        to_be_added = set()
        for symbol in new_symbols:
            # Normalize feartures
            if symbol.endswith("_MODULE"):
                symbol = symbol[:-len("_MODULE")]

            # Add _MODULE symbols
            if (symbol + "_MODULE") in self.model:
                to_be_added.add(symbol + "_MODULE")

            # Remove missing items in the first place
            if not symbol in self.model:
                to_be_removed.add(symbol)
                to_be_removed.add(symbol + "_MODULE")
        new_symbols = (new_symbols - to_be_removed).union(to_be_added)

        return new_symbols

    def __copy_selections(self, directory, base_symbols, current_selection, current_fileset):
        """
        @return a list of tulples: (subdir, symbols, selection, fileset)
        """
        file_selections = {}
        recursive_selections = []
        new_visited_dirs = self.visited_dirs

        for symbol in base_symbols:

            if symbol in current_selection.symbols:
                continue

            if not symbol in self.model:
                continue

            # Copy Selection
            new_selection = Selection(current_selection)
            new_selection.push_down()
            new_selection.add_alternative(symbol)
            new_fileset = self.file_set_cache.get_fileset(new_selection)

            ((f_added, _), (d_added, _)) = new_fileset.compare_to_base(current_fileset)

            for filename in f_added: # f_added
                if not filename in file_selections:
                    file_selections[filename] = Selection(new_selection)
                else:
                    file_selections[filename].add_alternative(symbol)

            # Is there a directory we haven't done recursion on yet,
            # so lets do a recursion step here.
            # We only consider subdirectories of the current directory
            new_subdirectories = d_added - self.visited_dirs
            new_subdirectories = set([dirname for dirname in new_subdirectories
                                      if dirname.startswith(directory) and
                                      dirname.startswith(self.directory_prefix)])
            if len(new_subdirectories) > 0:
                new_visited_dirs = new_visited_dirs.union(set(new_subdirectories))

                # If we want to go down recursive in a directory, we
                # add all symbols which are mentioned within the
                # directories Kbuild/Makefile
                for subdir in new_subdirectories:
                    new_symbols = self.check_subdir(subdir, new_selection.symbols)
                    recursive_selections.append( tuple([subdir,
                                                        new_symbols,
                                                        new_selection,
                                                        new_fileset]))

        self.visited_dirs = new_visited_dirs

        return (recursive_selections, file_selections)


    def __calculate(self, directory, base_symbols, current_selection, current_fileset):
        """
        The heart of the inferencer, here the recursion is done.
        """

        if not self.__subdirectory_is_worth_working_on(directory):
            return

        logging.info("Starting __calculate on %s with %d symbols (%d files so far)",
                     directory, len(base_symbols), len(self.file_selections))

        (recursive_selections, file_selections) =  \
            self.__copy_selections(directory, base_symbols,
                                   current_selection, current_fileset)

        # Collection phase
        for (filename, selection) in file_selections.items():
            if not filename in self.file_selections:
                self.file_selections[filename] = selection
            else:
                if selection.better_than(self.file_selections[filename]):
                    self.file_selections[filename] = selection
                else:
                    # Sometimes Expressions can be merged if they only
                    # differ in one or_expression
                    merged = self.file_selections[filename].merge(selection)
                    if merged:
                        self.file_selections[filename] = merged

        # RECURSION!
        for (subdir, symbols, selection, fileset) in recursive_selections:
            self.__calculate(subdir, symbols, selection, fileset)