def regex_ifndef_match(line, ifdef_condition, global_vars, model): """ Check if @line resembles a line describing a condition with if(n)def. If so, update the condition in @ifdef_condition and return True, otherwise return False.""" regex_match = REGEX_IFNDEF.match(line) if not regex_match: return False if global_vars["no_config_nesting"] > 0: global_vars.increment_variable("no_config_nesting") else: keyword = regex_match.group(1) rhs = regex_match.group(2) conf_results = REGEX_CONFIG.match(rhs) if conf_results: conf = Tools.get_config_string(conf_results.group(1),\ model) if keyword == "ifdef": ifdef_condition.add_condition(conf) else: ifdef_condition.add_condition("!" + conf) else: # Not parseable -> nesting level global_vars.increment_variable("no_config_nesting") return True
def regex_ifneq_match(line, ifdef_condition, global_vars, model): """ Check if @line resembles a line describing a condition with if(n)eq. If so, update the condition in @ifdef_condition and return True, otherwise return False.""" regex_match = REGEX_IFNEQ.match(line) if not regex_match: return False if global_vars["no_config_nesting"] > 0: global_vars.increment_variable("no_config_nesting") else: positive_keyword = (regex_match.group(1) != "ifneq") possible_conf = regex_match.group(2) conf_results = REGEX_IFNEQ_CONF.match(possible_conf) if conf_results: positive_comp = (conf_results.group(2) == "y" or conf_results.group(2) == "m") config = conf_results.group(1) conf = Tools.get_config_string(config, model) if positive_keyword == positive_comp: ifdef_condition.add_condition(conf) else: ifdef_condition.add_condition("!" + conf) else: global_vars.increment_variable("no_config_nesting") return True
def parse_architecture_regular(self, line, local_arch_dirs): """ Parse an architecture Makefile. This looks for any additional lists (core|init|drivers|net|libs) and saves the corresponding conditions for those directories.""" regex_match = self.regex_arch_spec.match(line) if not regex_match: return False current_precondition = DataStructures.Precondition() config_item = regex_match.group(2) if config_item != "y": config_item = regex_match.group(3) condition = Tools.get_config_string(config_item, self.model) current_precondition.add_condition(condition) rhs = regex_match.group(5) matches = [x for x in re.split("\t| ", rhs) if x] for match in matches: if not os.path.isdir(match): continue if match[-1] != '/': match += '/' logging.debug("adding match " + match + " with " + \ config_item) local_arch_dirs[match].append(current_precondition[:]) return True
def process(self, parser, line, basepath): line = line.processed_line regex_match = re.match(self.regex_obj, line) if not regex_match: return False rhs = regex_match.group(5) # First, check for match on core/lib/libs-y if regex_match.group(2) == "y": matches = [x for x in re.split("\t| ", rhs) if x] for match in matches: fullpath = basepath + "/" + match if os.path.isdir(fullpath): parser.local_vars["dir_cond_collection"][fullpath].\ add_alternative(parser.local_vars["ifdef_condition"][:]) else: sourcefile = Kbuild.guess_source_for_target(fullpath) if sourcefile: parser.local_vars["file_features"][sourcefile].\ add_alternative(parser.local_vars["ifdef_condition"][:]) else: parser.local_vars["composite_map"][fullpath].\ add_alternative(parser.local_vars["ifdef_condition"][:]) else: # Then test obj-$(CONFIG_XY) config = regex_match.group(3) condition = Tools.get_config_string(config, self.model) matches = [x for x in re.split("\t| ", rhs) if x] parser.local_vars["ifdef_condition"].add_condition(condition) for match in matches: fullpath = basepath + "/" + match if os.path.isdir(fullpath): parser.local_vars["dir_cond_collection"][fullpath].\ add_alternative(parser.local_vars["ifdef_condition"][:]) else: # Hacky bit for COMMON_FILES in this directory if basepath == "archival/libarchive": parser.local_vars["all_configs"].append(condition) sourcefile = Kbuild.\ guess_source_for_target(fullpath) if sourcefile: parser.local_vars["file_features"][sourcefile].\ add_alternative(parser.local_vars["ifdef_condition"][:]) else: parser.local_vars["composite_map"][fullpath].\ add_alternative(parser.local_vars["ifdef_condition"][:]) parser.local_vars["ifdef_condition"].pop() return True
def parse_blackfin_architecture(self, line, local_arch_dirs): """ Parse the Makefile at arch/blackfin/ and look for any lines describing machine-$(CONFIG_XY) lists.""" if self.arch != "blackfin": return False regex_match = self.regex_arm.match(line) if not regex_match: return False current_precondition = DataStructures.Precondition() lst = regex_match.group(1) config_item = regex_match.group(2) if config_item != "y": config_item = regex_match.group(3) condition = Tools.get_config_string(config_item, self.model) current_precondition.add_condition(condition) rhs = regex_match.group(5) matches = [x for x in re.split("\t| ", rhs) if x] for match in matches: if lst != "machine": # Should never happen in blackfin logging.error("plat- list should not be present in blackfin") continue fullpath = "arch/blackfin/mach-" + match if os.path.isdir(fullpath): if fullpath[-1] != '/': fullpath += '/' local_arch_dirs[fullpath].append(current_precondition[:]) fullpath = "arch/blackfin/mach-" + match + "/boards/" if os.path.isdir(fullpath): if fullpath[-1] != '/': fullpath += '/' local_arch_dirs[fullpath].append(current_precondition[:]) return True
def parse_arm_architecture(self, line, local_arch_dirs): """ Parse the Makefile at arch/arm/ and look for machine-$() and plat-$() lists describing the subdirectories.""" if self.arch != "arm": return False regex_match = self.regex_arm.match(line) if not regex_match: return False current_precondition = DataStructures.Precondition() lst = regex_match.group(1) config_item = regex_match.group(2) if config_item != "y": config_item = regex_match.group(3) condition = Tools.get_config_string(config_item, self.model) current_precondition.add_condition(condition) rhs = regex_match.group(5) matches = [x for x in re.split("\t| ", rhs) if x] for match in matches: fullpath = "" if lst == "machine": fullpath = "arch/arm/mach-" + match else: fullpath = "arch/arm/plat-" + match if not os.path.isdir(fullpath): continue if fullpath[-1] != '/': fullpath += '/' logging.debug("adding ARM match " + match + " with " + \ config_item) local_arch_dirs[fullpath].append(current_precondition[:]) return True
def expand_macro(self, name, path, condition, already_expanded, parser): """ Expand a macro named @name. Preconditions to the folder are given in @condition. The input file is @path and to avoid endless recursion processing is aborted if the current name is already present in @already_expanded. To save the results, the local variables are accessed via the @parser parameter.""" if name in already_expanded: return else: already_expanded.add(name) basepath = os.path.dirname(name) filename = os.path.basename(name) basename = "" # Extract base name from macro name match = self.regex_base.match(filename) if not match: return if match.group(1) is None: # we have a macro basename = match.group(2) if basename.endswith("y"): basename = basename[:-1] elif match.group(2) is None: # we have a file basename = match.group(1) scan_regex_string = "" if match.group(1) is None: scan_regex_string = r"\s*" + basename + r"(|y|\$\(" + \ CONFIG_FORMAT + r"\))\s*(:=|\+=|=)\s*(.*)" else: scan_regex_string = r"\s*" + basename + r"(|-y|-objs|-\$\(" + \ CONFIG_FORMAT + r"\))\s*(:=|\+=|=)\s*(.*)" scan_regex = re.compile(scan_regex_string) if not path in parser.file_content_cache: parser.read_whole_file(path) inputs = parser.file_content_cache[path] for line in inputs: if line.invalid: continue ifdef_condition = line.condition line = line.processed_line match = scan_regex.match(line) if not match: continue config_in_composite = match.group(2) condition_comp = "" if config_in_composite: condition_comp = Tools.get_config_string( config_in_composite, self.model) rhs = match.group(4) matches = [x for x in re.split("\t| ", rhs) if x] for item in matches: fullpath = basepath + "/" + item passdown_condition = condition[:] if config_in_composite: passdown_condition.append(condition_comp) if os.path.isdir(fullpath): parser.local_vars["dir_cond_collection"]\ [fullpath].add_alternative(passdown_condition[:]) else: sourcefile = Kbuild.guess_source_for_target(fullpath) if not sourcefile: self.expand_macro(fullpath, path, passdown_condition, already_expanded, parser) else: full_condition = DataStructures.Precondition() if len(condition) > 0: full_condition = condition[:] if config_in_composite: full_condition.append(condition_comp) if len(ifdef_condition) > 0: full_condition.extend(ifdef_condition) parser.local_vars["file_features"][sourcefile].\ add_alternative(full_condition[:]) already_expanded.discard(name)
def __process(self, parser, line, basepath): line = line.processed_line # Try obj-... +=/:=/= objfile.o regex_match = self.regex_obj.match(line) if regex_match: rhs = regex_match.group(5) # Fixes one special case in arch/mips/lib, could be extended with # other make-commands. if rhs.startswith("$(filter-out"): return False # First, check for match on obj-y or obj-m if regex_match.group(2) == "y" or regex_match.group(2) == "m": matches = [x for x in re.split("\t| ", rhs) if x] for match in matches: fullpath = basepath + "/" + match if os.path.isdir(fullpath): parser.local_vars["dir_cond_collection"][fullpath].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) else: sourcefile = Kbuild.guess_source_for_target(fullpath) if sourcefile: parser.local_vars["file_features"][sourcefile].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) else: parser.local_vars["composite_map"][fullpath].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) else: # Then test obj-$(CONFIG_XY) config = regex_match.group(3) condition = Tools.get_config_string(config, self.model) matches = [x for x in re.split("\t| ", rhs) if x] parser.local_vars["ifdef_condition"].add_condition(condition) for match in matches: fullpath = basepath + "/" + match if os.path.isdir(fullpath): # Has this directory been picked up via subdir-XY? if parser.local_vars["ifdef_condition"] in \ parser.local_vars["dir_cond_collection"][fullpath]: continue parser.local_vars["dir_cond_collection"][fullpath].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) else: sourcefile = Kbuild.guess_source_for_target(fullpath) if sourcefile: parser.local_vars["file_features"][sourcefile].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) else: parser.local_vars["composite_map"][fullpath].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) parser.local_vars["ifdef_condition"].pop() # Up to v3.15, the security/ subdir used only subdir-$(CONFIG..) for # descending into subdirectories. All other directories didn't... else: match = self.regex_subdir.match(line) if not match: return False # If subdir is conditional, add condition to ifdef_condition if match.group(1) != "y": condition = Tools.get_config_string(match.group(2), self.model) parser.local_vars["ifdef_condition"].add_condition(condition) rhs = match.group(3) rhs_matches = [x.rstrip("/") for x in re.split("\t| ", rhs) if x] for m in rhs_matches: fullpath = basepath + "/" + m + "/" if not os.path.isdir(fullpath): continue # Has this directory been picked up via obj-XY? if parser.local_vars["ifdef_condition"] in \ parser.local_vars["dir_cond_collection"][fullpath]: continue parser.local_vars["dir_cond_collection"][fullpath].\ add_alternative( parser.local_vars["ifdef_condition"][:] ) if match.group(1) != "y": parser.local_vars["ifdef_condition"].pop() return True