From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <gentoo-commits+bounces-1467251-garchives=archives.gentoo.org@lists.gentoo.org>
Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits))
	(No client certificate requested)
	by finch.gentoo.org (Postfix) with ESMTPS id E74DC158020
	for <garchives@archives.gentoo.org>; Thu, 15 Dec 2022 09:03:37 +0000 (UTC)
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id 0EB71E07E0;
	Thu, 15 Dec 2022 09:03:37 +0000 (UTC)
Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
	(No client certificate requested)
	by pigeon.gentoo.org (Postfix) with ESMTPS id EA631E07E0
	for <gentoo-commits@lists.gentoo.org>; Thu, 15 Dec 2022 09:03:36 +0000 (UTC)
Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id D86F2340E81
	for <gentoo-commits@lists.gentoo.org>; Thu, 15 Dec 2022 09:03:35 +0000 (UTC)
Received: from localhost.localdomain (localhost [IPv6:::1])
	by oystercatcher.gentoo.org (Postfix) with ESMTP id 27D15783
	for <gentoo-commits@lists.gentoo.org>; Thu, 15 Dec 2022 09:03:34 +0000 (UTC)
From: "Fabian Groffen" <grobian@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: 8bit
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Fabian Groffen" <grobian@gentoo.org>
Message-ID: <1671094962.8f7064fdf7aa08e00bb24e5e479c1df4be9ae5e7.grobian@gentoo>
Subject: [gentoo-commits] proj/portage-utils:master commit in: /
X-VCS-Repository: proj/portage-utils
X-VCS-Files: main.c
X-VCS-Directories: /
X-VCS-Committer: grobian
X-VCS-Committer-Name: Fabian Groffen
X-VCS-Revision: 8f7064fdf7aa08e00bb24e5e479c1df4be9ae5e7
X-VCS-Branch: master
Date: Thu, 15 Dec 2022 09:03:34 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply
X-Archives-Salt: efaababe-20ab-4522-822b-e35ed7a8b354
X-Archives-Hash: 0478010dfd71af7425f4ab7de2f8f7f5

commit:     8f7064fdf7aa08e00bb24e5e479c1df4be9ae5e7
Author:     Krzesimir Nowak <knowak <AT> microsoft <DOT> com>
AuthorDate: Wed Dec 14 11:53:33 2022 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Thu Dec 15 09:02:42 2022 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=8f7064fd

main: Handle empty repo names in parent files

Empty repo name is documented in portage(5).

Signed-off-by: Krzesimir Nowak <knowak <AT> microsoft.com>
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 main.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 16 deletions(-)

diff --git a/main.c b/main.c
index f6a39f9..347a50b 100644
--- a/main.c
+++ b/main.c
@@ -598,6 +598,65 @@ read_portage_file(const char *file, enum portage_file_type type, void *data)
 		fprintf(stderr, "read profile %s\n", file);
 }
 
+/* Helper to check if a string starts with a prefix. If so, returns
+ * true and gets the length of the prefix. Otherwise returns false,
+ * leaving the prefix length unmodified. */
+static bool
+starts_with(const char *str, const char *prefix, size_t *prefix_len)
+{
+	const char *s;
+	const char *p;
+	size_t len;
+
+	if (prefix == NULL) {
+		/* every string starts with a null string */
+		if (prefix_len != NULL)
+			*prefix_len = 0;
+		return true;
+	}
+	if (str == NULL)
+		/* null string only starts with a null string, and prefix isn't null */
+		return false;
+
+	len = 0;
+	for (s = str, p = prefix; *s != '\0' && *p != '\0'; ++s, ++p, ++len) {
+		if (*s != *p)
+			return false;
+	}
+	if (*p == '\0') {
+		if (prefix_len != NULL)
+			*prefix_len = len;
+		return true;
+	}
+	return false;
+}
+
+/* Helper to figure out inside of which overlay a path is. Returns
+ * null if nonesuch is found. */
+static const char *
+overlay_from_path (const char *path)
+{
+	size_t n;
+	char *overlay;
+	size_t max_match = 0;
+	const char *found_overlay = NULL;
+
+	array_for_each(overlays, n, overlay) {
+		size_t overlay_len;
+
+		if (!starts_with(path, overlay, &overlay_len))
+			continue;
+
+		if (overlay_len <= max_match)
+			continue;
+
+		max_match = overlay_len;
+		found_overlay = overlay;
+	}
+
+	return found_overlay;
+}
+
 /* Helper to recursively read stacked make.defaults in profiles */
 static void
 read_portage_profile(const char *profile, env_vars vars[], set *masks)
@@ -634,24 +693,38 @@ read_portage_profile(const char *profile, env_vars vars[], set *masks)
 				/* split repo from target */
 				*p++ = '\0';
 
-				/* match the repo */
-				repo_name = NULL;
-				array_for_each(overlays, n, overlay) {
-					repo_name = xarrayget(overlay_names, n);
-					if (strcmp(repo_name, s) == 0) {
-						snprintf(profile_file, sizeof(profile_file),
-								"%s/profiles/%s/", overlay, p);
-						break;
+				if (s[0] == '\0') {
+					/* empty repo name means a repo where the profile is */
+					const char* current_overlay = overlay_from_path (profile);
+					if (current_overlay == NULL) {
+						/* bring back the colon to see the ignored parent line */
+						*(--p) = ':';
+						warn("could not figure out current repo of profile %s, ignoring parent %s",
+							       profile, s);
+						continue;
 					}
+					snprintf(profile_file, sizeof(profile_file),
+							"%s/profiles/%s", current_overlay, p);
+				} else {
+					/* match the repo */
 					repo_name = NULL;
-				}
-				if (repo_name == NULL) {
-					/* bring back the colon to see the ignored parent line */
-					*(--p) = ':';
-					warn("ignoring parent with unknown repo in profile %s: %s",
-							profile, s);
-					continue;
-				}
+					array_for_each(overlays, n, overlay) {
+						repo_name = xarrayget(overlay_names, n);
+						if (strcmp(repo_name, s) == 0) {
+							snprintf(profile_file, sizeof(profile_file),
+									"%s/profiles/%s/", overlay, p);
+							break;
+						}
+						repo_name = NULL;
+					}
+					if (repo_name == NULL) {
+						/* bring back the colon to see the ignored parent line */
+						*(--p) = ':';
+						warn("ignoring parent with unknown repo in profile %s: %s",
+								profile, s);
+						continue;
+					}
+                                }
 			} else {
 				snprintf(profile_file + profile_len,
 						sizeof(profile_file) - profile_len, "%s", s);