From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 ; 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 ; 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 ; 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 ; Thu, 15 Dec 2022 09:03:34 +0000 (UTC) From: "Fabian Groffen" 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" 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: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail 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 microsoft com> AuthorDate: Wed Dec 14 11:53:33 2022 +0000 Commit: Fabian Groffen gentoo 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 microsoft.com> Signed-off-by: Fabian Groffen 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);