summaryrefslogtreecommitdiff
path: root/mesonbuild/utils
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-01-10 15:10:09 +0100
committerEli Schwartz <eschwartz93@gmail.com>2025-03-09 13:05:08 -0400
commit528696300afd3236e173242e1e09d1ac80dfec81 (patch)
treef3989f6d6c49e188201719dd13468e10128a755d /mesonbuild/utils
parent9c125a26dbf1b6ecc674df2bd1abc02ca48da2cd (diff)
downloadmeson-528696300afd3236e173242e1e09d1ac80dfec81.tar.gz
mesonlib: extract and optimize is_parent_path
Introduce an alternative to os.path.commonpath(name, path) == path, which is a common idiom throughout Meson. Call it is_parent_path just like the existing static method in Generator. It is a bit faster and handles drives on Windows without the need for an exception handler. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'mesonbuild/utils')
-rw-r--r--mesonbuild/utils/universal.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py
index 45c0b7c13..3481aaa88 100644
--- a/mesonbuild/utils/universal.py
+++ b/mesonbuild/utils/universal.py
@@ -124,6 +124,7 @@ __all__ = [
'is_netbsd',
'is_openbsd',
'is_osx',
+ 'is_parent_path',
'is_qnx',
'is_sunos',
'is_windows',
@@ -1113,6 +1114,26 @@ def determine_worker_count(varnames: T.Optional[T.List[str]] = None) -> int:
num_workers = 1
return num_workers
+def is_parent_path(parent: str, trial: str) -> bool:
+ '''Checks if @trial is a file under the directory @parent. Both @trial and @parent should be
+ adequately normalized, though empty and '.' segments in @parent and @trial are accepted
+ and discarded, matching the behavior of os.path.commonpath. Either both or none should
+ be absolute.'''
+ assert os.path.isabs(parent) == os.path.isabs(trial)
+ if is_windows():
+ parent = parent.replace('\\', '/')
+ trial = trial.replace('\\', '/')
+
+ split_parent = parent.split('/')
+ split_trial = trial.split('/')
+
+ split_parent = [c for c in split_parent if c and c != '.']
+ split_trial = [c for c in split_trial if c and c != '.']
+
+ components = len(split_parent)
+ return len(split_trial) >= components and split_trial[:components] == split_parent
+
+
def has_path_sep(name: str, sep: str = '/\\') -> bool:
'Checks if any of the specified @sep path separators are in @name'
for each in sep: