Пример #1
0
 def _parse_repository_usealiases(self, repositories):
     ret = {}
     for repo in repositories.repos_with_profiles():
         file_name = os.path.join(repo.location, "profiles", "use.aliases")
         eapi = read_corresponding_eapi_file(file_name, default=repo.eapi)
         useflag_re = _get_useflag_re(eapi)
         raw_file_dict = grabdict(file_name, recursive=True)
         file_dict = {}
         for real_flag, aliases in raw_file_dict.items():
             if useflag_re.match(real_flag) is None:
                 writemsg(_("--- Invalid real USE flag in '%s': '%s'\n") %
                          (file_name, real_flag),
                          noiselevel=-1)
             else:
                 for alias in aliases:
                     if useflag_re.match(alias) is None:
                         writemsg(_(
                             "--- Invalid USE flag alias for '%s' real USE flag in '%s': '%s'\n"
                         ) % (real_flag, file_name, alias),
                                  noiselevel=-1)
                     else:
                         if any(alias in v for k, v in file_dict.items()
                                if k != real_flag):
                             writemsg(_(
                                 "--- Duplicated USE flag alias in '%s': '%s'\n"
                             ) % (file_name, alias),
                                      noiselevel=-1)
                         else:
                             file_dict.setdefault(real_flag,
                                                  []).append(alias)
         ret[repo.name] = file_dict
     return ret
Пример #2
0
 def _parse_file_to_tuple(self,
                          file_name,
                          recursive=True,
                          eapi_filter=None):
     ret = []
     lines = grabfile(file_name, recursive=recursive)
     eapi = read_corresponding_eapi_file(file_name)
     if eapi_filter is not None and not eapi_filter(eapi):
         if lines:
             writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
                      (eapi, os.path.basename(file_name), file_name),
                      noiselevel=-1)
         return ()
     useflag_re = _get_useflag_re(eapi)
     for prefixed_useflag in lines:
         if prefixed_useflag[:1] == "-":
             useflag = prefixed_useflag[1:]
         else:
             useflag = prefixed_useflag
         if useflag_re.match(useflag) is None:
             writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
                      (file_name, prefixed_useflag),
                      noiselevel=-1)
         else:
             ret.append(prefixed_useflag)
     return tuple(ret)
Пример #3
0
	def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True):
		ret = {}
		location_dict = {}
		file_dict = grabdict_package(file_name, recursive=recursive, verify_eapi=True)
		eapi = read_corresponding_eapi_file(file_name)
		useflag_re = _get_useflag_re(eapi)
		for k, v in file_dict.items():
			useflags = []
			for prefixed_useflag in v:
				if prefixed_useflag[:1] == "-":
					useflag = prefixed_useflag[1:]
				else:
					useflag = prefixed_useflag
				if useflag_re.match(useflag) is None:
					writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
						(k, file_name, prefixed_useflag), noiselevel=-1)
				else:
					useflags.append(prefixed_useflag)
			location_dict.setdefault(k, []).extend(useflags)
		for k, v in location_dict.items():
			if juststrings:
				v = " ".join(v)
			else:
				v = tuple(v)
			ret.setdefault(k.cp, {})[k] = v
		return ret
Пример #4
0
	def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True, eapi_filter=None):
		ret = {}
		location_dict = {}
		file_dict = grabdict_package(file_name, recursive=recursive, verify_eapi=True)
		eapi = read_corresponding_eapi_file(file_name)
		if eapi_filter is not None and not eapi_filter(eapi):
			if file_dict:
				writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
					(eapi, os.path.basename(file_name), file_name),
					noiselevel=-1)
			return ret
		useflag_re = _get_useflag_re(eapi)
		for k, v in file_dict.items():
			useflags = []
			for prefixed_useflag in v:
				if prefixed_useflag[:1] == "-":
					useflag = prefixed_useflag[1:]
				else:
					useflag = prefixed_useflag
				if useflag_re.match(useflag) is None:
					writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
						(k, file_name, prefixed_useflag), noiselevel=-1)
				else:
					useflags.append(prefixed_useflag)
			location_dict.setdefault(k, []).extend(useflags)
		for k, v in location_dict.items():
			if juststrings:
				v = " ".join(v)
			else:
				v = tuple(v)
			ret.setdefault(k.cp, {})[k] = v
		return ret
Пример #5
0
	def _parse_repository_usealiases(self, repositories):
		ret = {}
		for repo in repositories.repos_with_profiles():
			file_name = os.path.join(repo.location, "profiles", "use.aliases")
			eapi = read_corresponding_eapi_file(
				file_name, default=repo.eapi)
			useflag_re = _get_useflag_re(eapi)
			raw_file_dict = grabdict(file_name, recursive=True)
			file_dict = {}
			for real_flag, aliases in raw_file_dict.items():
				if useflag_re.match(real_flag) is None:
					writemsg(_("--- Invalid real USE flag in '%s': '%s'\n") % (file_name, real_flag), noiselevel=-1)
				else:
					for alias in aliases:
						if useflag_re.match(alias) is None:
							writemsg(_("--- Invalid USE flag alias for '%s' real USE flag in '%s': '%s'\n") %
								(real_flag, file_name, alias), noiselevel=-1)
						else:
							if any(alias in v for k, v in file_dict.items() if k != real_flag):
								writemsg(_("--- Duplicated USE flag alias in '%s': '%s'\n") %
									(file_name, alias), noiselevel=-1)
							else:
								file_dict.setdefault(real_flag, []).append(alias)
			ret[repo.name] = file_dict
		return ret
Пример #6
0
 def _parse_repository_packageusealiases(self, repositories):
     ret = {}
     for repo in repositories.repos_with_profiles():
         file_name = os.path.join(repo.location, "profiles",
                                  "package.use.aliases")
         eapi = read_corresponding_eapi_file(file_name, default=repo.eapi)
         useflag_re = _get_useflag_re(eapi)
         lines = grabfile(file_name, recursive=True)
         file_dict = {}
         for line in lines:
             elements = line.split()
             atom = elements[0]
             try:
                 atom = Atom(atom, eapi=eapi)
             except InvalidAtom:
                 writemsg(
                     _("--- Invalid atom in '%s': '%s'\n") %
                     (file_name, atom))
                 continue
             if len(elements) == 1:
                 writemsg(
                     _("--- Missing real USE flag for '%s' in '%s'\n") %
                     (atom, file_name),
                     noiselevel=-1,
                 )
                 continue
             real_flag = elements[1]
             if useflag_re.match(real_flag) is None:
                 writemsg(
                     _("--- Invalid real USE flag for '%s' in '%s': '%s'\n")
                     % (atom, file_name, real_flag),
                     noiselevel=-1,
                 )
             else:
                 for alias in elements[2:]:
                     if useflag_re.match(alias) is None:
                         writemsg(
                             _("--- Invalid USE flag alias for '%s' real USE flag for '%s' in '%s': '%s'\n"
                               ) % (real_flag, atom, file_name, alias),
                             noiselevel=-1,
                         )
                     else:
                         # Duplicated USE flag aliases in entries for different atoms
                         # matching the same package version are detected in getUseAliases().
                         if any(alias in v for k, v in file_dict.get(
                                 atom.cp, {}).get(atom, {}).items()
                                if k != real_flag):
                             writemsg(
                                 _("--- Duplicated USE flag alias for '%s' in '%s': '%s'\n"
                                   ) % (atom, file_name, alias),
                                 noiselevel=-1,
                             )
                         else:
                             file_dict.setdefault(atom.cp, {}).setdefault(
                                 atom, {}).setdefault(real_flag,
                                                      []).append(alias)
         ret[repo.name] = file_dict
     return ret
Пример #7
0
 def _parse_file_to_tuple(self,
                          file_name,
                          recursive=True,
                          eapi_filter=None,
                          eapi=None,
                          eapi_default="0"):
     """
     @param file_name: input file name
     @type file_name: str
     @param recursive: triggers recursion if the input file is a
             directory
     @type recursive: bool
     @param eapi_filter: a function that accepts a single eapi
             argument, and returns true if the current file type
             is supported by the given EAPI
     @type eapi_filter: callable
     @param eapi: the EAPI of the current profile node, which allows
             a call to read_corresponding_eapi_file to be skipped
     @type eapi: str
     @param eapi_default: the default EAPI which applies if the
             current profile node does not define a local EAPI
     @type eapi_default: str
     @rtype: tuple
     @return: collection of USE flags
     """
     ret = []
     lines = grabfile(file_name, recursive=recursive)
     if eapi is None:
         eapi = read_corresponding_eapi_file(file_name,
                                             default=eapi_default)
     if eapi_filter is not None and not eapi_filter(eapi):
         if lines:
             writemsg(
                 _("--- EAPI '%s' does not support '%s': '%s'\n") %
                 (eapi, os.path.basename(file_name), file_name),
                 noiselevel=-1,
             )
         return ()
     useflag_re = _get_useflag_re(eapi)
     for prefixed_useflag in lines:
         if prefixed_useflag[:1] == "-":
             useflag = prefixed_useflag[1:]
         else:
             useflag = prefixed_useflag
         if useflag_re.match(useflag) is None:
             writemsg(
                 _("--- Invalid USE flag in '%s': '%s'\n") %
                 (file_name, prefixed_useflag),
                 noiselevel=-1,
             )
         else:
             ret.append(prefixed_useflag)
     return tuple(ret)
Пример #8
0
 def _parse_repository_packageusealiases(self, repositories):
     ret = {}
     for repo in repositories.repos_with_profiles():
         file_name = os.path.join(repo.location, "profiles", "package.use.aliases")
         eapi = read_corresponding_eapi_file(file_name)
         useflag_re = _get_useflag_re(eapi)
         lines = grabfile(file_name, recursive=True)
         file_dict = {}
         for line in lines:
             elements = line.split()
             atom = elements[0]
             try:
                 atom = Atom(atom, eapi=eapi)
             except InvalidAtom:
                 writemsg(_("--- Invalid atom in '%s': '%s'\n") % (file_name, atom))
                 continue
             if len(elements) == 1:
                 writemsg(_("--- Missing real USE flag for '%s' in '%s'\n") % (atom, file_name), noiselevel=-1)
                 continue
             real_flag = elements[1]
             if useflag_re.match(real_flag) is None:
                 writemsg(
                     _("--- Invalid real USE flag for '%s' in '%s': '%s'\n") % (atom, file_name, real_flag),
                     noiselevel=-1,
                 )
             else:
                 for alias in elements[2:]:
                     if useflag_re.match(alias) is None:
                         writemsg(
                             _("--- Invalid USE flag alias for '%s' real USE flag for '%s' in '%s': '%s'\n")
                             % (real_flag, atom, file_name, alias),
                             noiselevel=-1,
                         )
                     else:
                         # Duplicated USE flag aliases in entries for different atoms
                         # matching the same package version are detected in getUseAliases().
                         if any(
                             alias in v
                             for k, v in file_dict.get(atom.cp, {}).get(atom, {}).items()
                             if k != real_flag
                         ):
                             writemsg(
                                 _("--- Duplicated USE flag alias for '%s' in '%s': '%s'\n")
                                 % (atom, file_name, alias),
                                 noiselevel=-1,
                             )
                         else:
                             file_dict.setdefault(atom.cp, {}).setdefault(atom, {}).setdefault(real_flag, []).append(
                                 alias
                             )
         ret[repo.name] = file_dict
     return ret
Пример #9
0
 def _parse_file_to_dict(self,
                         file_name,
                         juststrings=False,
                         recursive=True,
                         eapi_filter=None,
                         user_config=False):
     ret = {}
     location_dict = {}
     eapi = read_corresponding_eapi_file(file_name, default=None)
     if eapi is None and not user_config:
         eapi = "0"
     if eapi is None:
         ret = ExtendedAtomDict(dict)
     else:
         ret = {}
     file_dict = grabdict_package(file_name,
                                  recursive=recursive,
                                  allow_wildcard=(eapi is None),
                                  allow_repo=(eapi is None),
                                  verify_eapi=(eapi is not None))
     if eapi is not None and eapi_filter is not None and not eapi_filter(
             eapi):
         if file_dict:
             writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
                      (eapi, os.path.basename(file_name), file_name),
                      noiselevel=-1)
         return ret
     useflag_re = _get_useflag_re(eapi)
     for k, v in file_dict.items():
         useflags = []
         for prefixed_useflag in v:
             if prefixed_useflag[:1] == "-":
                 useflag = prefixed_useflag[1:]
             else:
                 useflag = prefixed_useflag
             if useflag_re.match(useflag) is None:
                 writemsg(
                     _("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
                     (k, file_name, prefixed_useflag),
                     noiselevel=-1)
             else:
                 useflags.append(prefixed_useflag)
         location_dict.setdefault(k, []).extend(useflags)
     for k, v in location_dict.items():
         if juststrings:
             v = " ".join(v)
         else:
             v = tuple(v)
         ret.setdefault(k.cp, {})[k] = v
     return ret
Пример #10
0
	def _parse_file_to_tuple(self, file_name, recursive=True):
		ret = []
		lines = grabfile(file_name, recursive=recursive)
		eapi = read_corresponding_eapi_file(file_name)
		useflag_re = _get_useflag_re(eapi)
		for prefixed_useflag in lines:
			if prefixed_useflag[:1] == "-":
				useflag = prefixed_useflag[1:]
			else:
				useflag = prefixed_useflag
			if useflag_re.match(useflag) is None:
				writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
					(file_name, prefixed_useflag), noiselevel=-1)
			else:
				ret.append(prefixed_useflag)
		return tuple(ret)
Пример #11
0
	def _parse_file_to_tuple(self, file_name, recursive=True,
		eapi_filter=None, eapi=None, eapi_default="0"):
		"""
		@param file_name: input file name
		@type file_name: str
		@param recursive: triggers recursion if the input file is a
			directory
		@type recursive: bool
		@param eapi_filter: a function that accepts a single eapi
			argument, and returns true if the the current file type
			is supported by the given EAPI
		@type eapi_filter: callable
		@param eapi: the EAPI of the current profile node, which allows
			a call to read_corresponding_eapi_file to be skipped
		@type eapi: str
		@param eapi_default: the default EAPI which applies if the
			current profile node does not define a local EAPI
		@type eapi_default: str
		@rtype: tuple
		@return: collection of USE flags
		"""
		ret = []
		lines = grabfile(file_name, recursive=recursive)
		if eapi is None:
			eapi = read_corresponding_eapi_file(
				file_name, default=eapi_default)
		if eapi_filter is not None and not eapi_filter(eapi):
			if lines:
				writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
					(eapi, os.path.basename(file_name), file_name),
					noiselevel=-1)
			return ()
		useflag_re = _get_useflag_re(eapi)
		for prefixed_useflag in lines:
			if prefixed_useflag[:1] == "-":
				useflag = prefixed_useflag[1:]
			else:
				useflag = prefixed_useflag
			if useflag_re.match(useflag) is None:
				writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
					(file_name, prefixed_useflag), noiselevel=-1)
			else:
				ret.append(prefixed_useflag)
		return tuple(ret)
Пример #12
0
	def _parse_file_to_tuple(self, file_name, recursive=True, eapi_filter=None):
		ret = []
		lines = grabfile(file_name, recursive=recursive)
		eapi = read_corresponding_eapi_file(file_name)
		if eapi_filter is not None and not eapi_filter(eapi):
			if lines:
				writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
					(eapi, os.path.basename(file_name), file_name),
					noiselevel=-1)
			return ()
		useflag_re = _get_useflag_re(eapi)
		for prefixed_useflag in lines:
			if prefixed_useflag[:1] == "-":
				useflag = prefixed_useflag[1:]
			else:
				useflag = prefixed_useflag
			if useflag_re.match(useflag) is None:
				writemsg(_("--- Invalid USE flag in '%s': '%s'\n") %
					(file_name, prefixed_useflag), noiselevel=-1)
			else:
				ret.append(prefixed_useflag)
		return tuple(ret)
Пример #13
0
    def _parse_file_to_dict(self,
                            file_name,
                            juststrings=False,
                            recursive=True,
                            eapi_filter=None,
                            user_config=False,
                            eapi=None,
                            eapi_default="0",
                            allow_build_id=False):
        """
		@param file_name: input file name
		@type file_name: str
		@param juststrings: store dict values as space-delimited strings
			instead of tuples
		@type juststrings: bool
		@param recursive: triggers recursion if the input file is a
			directory
		@type recursive: bool
		@param eapi_filter: a function that accepts a single eapi
			argument, and returns true if the the current file type
			is supported by the given EAPI
		@type eapi_filter: callable
		@param user_config: current file is part of the local
			configuration (not repository content)
		@type user_config: bool
		@param eapi: the EAPI of the current profile node, which allows
			a call to read_corresponding_eapi_file to be skipped
		@type eapi: str
		@param eapi_default: the default EAPI which applies if the
			current profile node does not define a local EAPI
		@type eapi_default: str
		@param allow_build_id: allow atoms to specify a particular
			build-id
		@type allow_build_id: bool
		@rtype: tuple
		@return: collection of USE flags
		"""
        ret = {}
        location_dict = {}
        if eapi is None:
            eapi = read_corresponding_eapi_file(file_name,
                                                default=eapi_default)
        extended_syntax = eapi is None and user_config
        if extended_syntax:
            ret = ExtendedAtomDict(dict)
        else:
            ret = {}
        file_dict = grabdict_package(file_name,
                                     recursive=recursive,
                                     allow_wildcard=extended_syntax,
                                     allow_repo=extended_syntax,
                                     verify_eapi=(not extended_syntax),
                                     eapi=eapi,
                                     eapi_default=eapi_default,
                                     allow_build_id=allow_build_id,
                                     allow_use=False)
        if eapi is not None and eapi_filter is not None and not eapi_filter(
                eapi):
            if file_dict:
                writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
                         (eapi, os.path.basename(file_name), file_name),
                         noiselevel=-1)
            return ret
        useflag_re = _get_useflag_re(eapi)
        for k, v in file_dict.items():
            useflags = []
            use_expand_prefix = ''
            for prefixed_useflag in v:
                if extended_syntax and prefixed_useflag == "\n":
                    use_expand_prefix = ""
                    continue
                if extended_syntax and prefixed_useflag[-1] == ":":
                    use_expand_prefix = prefixed_useflag[:-1].lower() + "_"
                    continue

                if prefixed_useflag[:1] == "-":
                    useflag = use_expand_prefix + prefixed_useflag[1:]
                    prefixed_useflag = "-" + useflag
                else:
                    useflag = use_expand_prefix + prefixed_useflag
                    prefixed_useflag = useflag
                if useflag_re.match(useflag) is None:
                    writemsg(
                        _("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
                        (k, file_name, prefixed_useflag),
                        noiselevel=-1)
                else:
                    useflags.append(prefixed_useflag)
            location_dict.setdefault(k, []).extend(useflags)
        for k, v in location_dict.items():
            if juststrings:
                v = " ".join(v)
            else:
                v = tuple(v)
            ret.setdefault(k.cp, {})[k] = v
        return ret
Пример #14
0
def expand_new_virt(vardb, atom):
    """
	Iterate over the recursively expanded RDEPEND atoms of
	a new-style virtual. If atom is not a new-style virtual
	or it does not match an installed package then it is
	yielded without any expansion.
	"""
    if not isinstance(atom, Atom):
        atom = Atom(atom)

    if not atom.cp.startswith("virtual/"):
        yield atom
        return

    traversed = set()
    stack = [atom]

    while stack:
        atom = stack.pop()
        if atom.blocker or \
         not atom.cp.startswith("virtual/"):
            yield atom
            continue

        matches = vardb.match(atom)
        if not (matches and matches[-1].startswith("virtual/")):
            yield atom
            continue

        virt_cpv = matches[-1]
        if virt_cpv in traversed:
            continue

        traversed.add(virt_cpv)
        eapi, iuse, rdepend, use = vardb.aux_get(
            virt_cpv, ["EAPI", "IUSE", "RDEPEND", "USE"])
        if not portage.eapi_is_supported(eapi):
            yield atom
            continue

        eapi_attrs = _get_eapi_attrs(eapi)
        # Validate IUSE and IUSE, for early detection of vardb corruption.
        useflag_re = _get_useflag_re(eapi)
        valid_iuse = []
        for x in iuse.split():
            if x[:1] in ("+", "-"):
                x = x[1:]
            if useflag_re.match(x) is not None:
                valid_iuse.append(x)
        valid_iuse = frozenset(valid_iuse)

        if eapi_attrs.iuse_effective:
            iuse_implicit_match = vardb.settings._iuse_effective_match
        else:
            iuse_implicit_match = vardb.settings._iuse_implicit_match

        valid_use = []
        for x in use.split():
            if x in valid_iuse or iuse_implicit_match(x):
                valid_use.append(x)
        valid_use = frozenset(valid_use)

        success, atoms = portage.dep_check(rdepend,
                                           None,
                                           vardb.settings,
                                           myuse=valid_use,
                                           myroot=vardb.settings['EROOT'],
                                           trees={
                                               vardb.settings['EROOT']: {
                                                   "porttree": vardb.vartree,
                                                   "vartree": vardb.vartree
                                               }
                                           })

        if success:
            stack.extend(atoms)
        else:
            yield atom
def expand_new_virt(vardb, atom):
	"""
	Iterate over the recursively expanded RDEPEND atoms of
	a new-style virtual. If atom is not a new-style virtual
	or it does not match an installed package then it is
	yielded without any expansion.
	"""
	if not isinstance(atom, Atom):
		atom = Atom(atom)

	if not atom.cp.startswith("virtual/"):
		yield atom
		return

	traversed = set()
	stack = [atom]

	while stack:
		atom = stack.pop()
		if atom.blocker or \
			not atom.cp.startswith("virtual/"):
			yield atom
			continue

		matches = vardb.match(atom)
		if not (matches and matches[-1].startswith("virtual/")):
			yield atom
			continue

		virt_cpv = matches[-1]
		if virt_cpv in traversed:
			continue

		traversed.add(virt_cpv)
		eapi, iuse, rdepend, use = vardb.aux_get(virt_cpv,
			["EAPI", "IUSE", "RDEPEND", "USE"])
		if not portage.eapi_is_supported(eapi):
			yield atom
			continue

		# Validate IUSE and IUSE, for early detection of vardb corruption.
		useflag_re = _get_useflag_re(eapi)
		valid_iuse = []
		for x in iuse.split():
			if x[:1] in ("+", "-"):
				x = x[1:]
			if useflag_re.match(x) is not None:
				valid_iuse.append(x)
		valid_iuse = frozenset(valid_iuse)

		iuse_implicit_match = vardb.settings._iuse_implicit_match
		valid_use = []
		for x in use.split():
			if x in valid_iuse or iuse_implicit_match(x):
				valid_use.append(x)
		valid_use = frozenset(valid_use)

		success, atoms = portage.dep_check(rdepend,
			None, vardb.settings, myuse=valid_use,
			myroot=vardb.settings['EROOT'],
			trees={vardb.settings['EROOT']:{"porttree":vardb.vartree,
			"vartree":vardb.vartree}})

		if success:
			stack.extend(atoms)
		else:
			yield atom
Пример #16
0
	def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True,
		eapi_filter=None, user_config=False, eapi=None, eapi_default="0"):
		"""
		@param file_name: input file name
		@type file_name: str
		@param juststrings: store dict values as space-delimited strings
			instead of tuples
		@type juststrings: bool
		@param recursive: triggers recursion if the input file is a
			directory
		@type recursive: bool
		@param eapi_filter: a function that accepts a single eapi
			argument, and returns true if the the current file type
			is supported by the given EAPI
		@type eapi_filter: callable
		@param user_config: current file is part of the local
			configuration (not repository content)
		@type user_config: bool
		@param eapi: the EAPI of the current profile node, which allows
			a call to read_corresponding_eapi_file to be skipped
		@type eapi: str
		@param eapi_default: the default EAPI which applies if the
			current profile node does not define a local EAPI
		@type eapi_default: str
		@rtype: tuple
		@return: collection of USE flags
		"""
		ret = {}
		location_dict = {}
		if eapi is None:
			eapi = read_corresponding_eapi_file(file_name,
				default=eapi_default)
		extended_syntax = eapi is None and user_config
		if extended_syntax:
			ret = ExtendedAtomDict(dict)
		else:
			ret = {}
		file_dict = grabdict_package(file_name, recursive=recursive,
			allow_wildcard=extended_syntax, allow_repo=extended_syntax,
			verify_eapi=(not extended_syntax), eapi=eapi,
			eapi_default=eapi_default)
		if eapi is not None and eapi_filter is not None and not eapi_filter(eapi):
			if file_dict:
				writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") %
					(eapi, os.path.basename(file_name), file_name),
					noiselevel=-1)
			return ret
		useflag_re = _get_useflag_re(eapi)
		for k, v in file_dict.items():
			useflags = []
			for prefixed_useflag in v:
				if prefixed_useflag[:1] == "-":
					useflag = prefixed_useflag[1:]
				else:
					useflag = prefixed_useflag
				if useflag_re.match(useflag) is None:
					writemsg(_("--- Invalid USE flag for '%s' in '%s': '%s'\n") %
						(k, file_name, prefixed_useflag), noiselevel=-1)
				else:
					useflags.append(prefixed_useflag)
			location_dict.setdefault(k, []).extend(useflags)
		for k, v in location_dict.items():
			if juststrings:
				v = " ".join(v)
			else:
				v = tuple(v)
			ret.setdefault(k.cp, {})[k] = v
		return ret