Fix a bug where if the first argument of _get_relative was an empty string the second path was not properly normalized before returning.
Redirect get_relative call to paths.bzl
Delete unused methods.
PiperOrigin-RevId: 505677440
Change-Id: Ic8cf80b112c53805b36149f01b187b3a3eed4fd7
diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl
index 2150b84..31eb6f4 100644
--- a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl
@@ -15,6 +15,7 @@
"""Utility functions for C++ rules."""
load(":common/objc/semantics.bzl", objc_semantics = "semantics")
+load(":common/paths.bzl", "paths")
CcInfo = _builtins.toplevel.CcInfo
cc_common = _builtins.toplevel.cc_common
@@ -420,25 +421,6 @@
DISALLOWED_HDRS_FILES = DISALLOWED_HDRS_FILES, # Also includes VERSIONED_SHARED_LIBRARY files.
)
-def _collect_header_tokens(
- ctx,
- cpp_configuration,
- compilation_outputs,
- process_hdrs,
- add_self_tokens):
- header_tokens_transitive = []
- for dep in ctx.attr.deps:
- if "_hidden_header_tokens_INTERNAL_" in dep[OutputGroupInfo]:
- header_tokens_transitive.append(dep[OutputGroupInfo]["_hidden_header_tokens_INTERNAL_"])
- else:
- header_tokens_transitive.append(depset([]))
-
- header_tokens_direct = []
- if add_self_tokens and process_hdrs:
- header_tokens_direct.extend(compilation_outputs.header_tokens())
-
- return depset(direct = header_tokens_direct, transitive = header_tokens_transitive)
-
def _collect_library_hidden_top_level_artifacts(
ctx,
files_to_compile):
@@ -1052,107 +1034,6 @@
def _is_repository_main(repository):
return repository == ""
-def _get_drive_str_length(path):
- if len(path) == 0:
- return 0
- if path[0] == "/":
- return 1
- return 0
-
-def _needs_to_normalize(path):
- dot_count = 0
- prev_char = ""
- for i in range(len(path)):
- c = path[i]
- if c == "\\":
- return True
- if c == "/":
- if prev_char == "/":
- return True
- if dot_count == 1 or dot_count == 2:
- return True
- if c == ".":
- dot_count += 1
- else:
- dot_count = 0
- prev_char = c
- if prev_char == "/" or dot_count == 1 or dot_count == 2:
- return True
- return False
-
-# Normalizes any '.' and '..' in-place in the segment list by shifting other segments to the
-# front. Returns the remaining number of items.
-def _remove_relative_paths(segments, is_absolute, start_index = 0):
- segment_count = 0
- shift = start_index
- for i in range(start_index, len(segments)):
- segment = segments[i]
- if segment == ".":
- shift += 1
- continue
- if segment == "..":
- if segment_count > 0 and segments[segment_count - 1] != "..":
- # Remove the last segment, if there is one and it is not "..". This
- # means that the resulting path can still contain ".."
- # segments at the beginning.
- segment_count -= 1
- shift += 2
- continue
- elif is_absolute:
- # If this is absolute, then just pop it the ".." off and remain at root
- shift += 1
- continue
- segment_count += 1
- if shift > 0:
- segments[i - shift] = segments[i]
- return segment_count
-
-def _normalize(path):
- if len(path) == 0:
- return path
- is_absolute = path[0] == "/"
- result = []
- if is_absolute:
- result.append("/")
- segments = path.split("/")
- segment_count = _remove_relative_paths(segments, is_absolute)
-
- # segment_count might not be the same as len(segments)
- for i in range(segment_count):
- result.append(segments[i])
- result.append("/")
-
- # Remove trailing "/".
- if segment_count > 0:
- result = result[:-1]
- return "".join(result)
-
-def _get_relative(original, other):
- if len(original) == 0:
- return other
- if len(other) == 0:
- return original
-
- other_drive_str_length = _get_drive_str_length(other)
- needs_to_normalize = _needs_to_normalize(other)
-
- # This is an absolute path, simply return it.
- if other_drive_str_length > 0:
- normalized_path = other
- if needs_to_normalize:
- normalized_path = _normalize(other)
- return normalized_path
- new_path = ""
- if original.endswith("/"):
- original = original[:-1]
- if other.endswith("/"):
- other = other[:-1]
-
- new_path = original + "/" + other
- if needs_to_normalize:
- return _normalize(new_path)
- return new_path
-
def _repository_exec_path(ctx, sibling_repository_layout):
repository = ctx.label.workspace_name
if _is_repository_main(repository):
@@ -1162,10 +1043,10 @@
prefix = ".."
if repository.startswith("@"):
repository = repository[1:]
- return _get_relative(prefix, repository)
+ return paths.get_relative(prefix, repository)
def _package_exec_path(ctx, package, sibling_repository_layout):
- return _get_relative(_repository_exec_path(ctx, sibling_repository_layout), package)
+ return paths.get_relative(_repository_exec_path(ctx, sibling_repository_layout), package)
def _package_source_root(ctx, package, sibling_repository_layout):
repository = ctx.label.workspace_name
@@ -1173,7 +1054,7 @@
return package
if repository.startswith("@"):
repository = repository[1:]
- return _get_relative(_get_relative("external", repository), package)
+ return paths.get_relative(paths.get_relative("external", repository), package)
def _contains_up_level_references(path):
return path.startswith("..") and (len(path) == 2 or path[2] == "/")
@@ -1188,11 +1069,11 @@
includes_attr = _expand(ctx, include, additional_make_variable_substitutions)
if includes_attr.startswith("/"):
continue
- includes_path = _get_relative(package_exec_path, includes_attr)
+ includes_path = paths.get_relative(package_exec_path, includes_attr)
if not sibling_repository_layout and _contains_up_level_references(includes_path):
fail("Path references a path above the execution root.", attr = "includes")
- if len(includes_path) == 0:
+ if includes_path == ".":
fail("'" + includes_attr + "' resolves to the workspace root, which would allow this rule and all of its " +
"transitive dependents to include any file in your workspace. Please include only" +
" what you need", attr = "includes")
@@ -1200,10 +1081,10 @@
# We don't need to perform the above checks against out_includes_path again since any errors
# must have manifested in includesPath already.
- out_includes_path = _get_relative(package_source_root, includes_attr)
+ out_includes_path = paths.get_relative(package_source_root, includes_attr)
if (ctx.configuration.has_separate_genfiles_directory()):
- result.append(_get_relative(ctx.genfiles_dir.path, out_includes_path))
- result.append(_get_relative(ctx.bin_dir.path, out_includes_path))
+ result.append(paths.get_relative(ctx.genfiles_dir.path, out_includes_path))
+ result.append(paths.get_relative(ctx.bin_dir.path, out_includes_path))
return result
def _get_coverage_environment(ctx, cc_config, cc_toolchain):