// trimPath cleans up a path by removing prefixes that are commonly
// found on profiles plus configured prefixes.
// TODO(aalexand): Consider optimizing out the redundant work done in this
// function if it proves to matter.
336403
func trimPath(path, trimPath, searchPath string) string {
	// Keep path variable intact as it's used below to form the return value.
	sPath, searchPath := filepath.ToSlash(path), filepath.ToSlash(searchPath)
	if trimPath == "" {
		// If the trim path is not configured, try to guess it heuristically:
		// search for basename of each search path in the original path and, if
		// found, strip everything up to and including the basename. So, for
		// example, given original path "/some/remote/path/my-project/foo/bar.c"
		// and search path "/my/local/path/my-project" the heuristic will return
		// "/my/local/path/my-project/foo/bar.c".
		for _, dir := range filepath.SplitList(searchPath) {
			want := "/" + filepath.Base(dir) + "/"
			if found := strings.Index(sPath, want); found != -1 {
				return path[found+len(want):]
			}
		}
	}
	// Trim configured trim prefixes.
	trimPaths := append(filepath.SplitList(filepath.ToSlash(trimPath)), "/proc/self/cwd/./", "/proc/self/cwd/")
	for _, trimPath := range trimPaths {
		if !strings.HasSuffix(trimPath, "/") {
			trimPath += "/"
		}
		if strings.HasPrefix(sPath, trimPath) {
			return path[len(trimPath):]
		}
	}
	return path
}
804240
func (d *driver) fullPath(subPath string) string {
	return path.Join(d.rootDirectory, subPath)
}
1319001
func NormalizePath(path string) string {
	pointer, err := filepath.EvalSymlinks(path)
	if err != nil {
		return path
	}
	abs, err := filepath.Abs(pointer)
	if err != nil {
		return pointer
	}
	return abs
}
742916
func (c *context) fullpath(p string) (string, error) {
	p = c.pathDriver.Join(c.root, p)
	if !strings.HasPrefix(p, c.root) {
		return "", fmt.Errorf("invalid context path")
	}

	return p, nil
}
912530
func (p *PathManager) RemovePaths(paths []string) {
	p.l.Lock()
	defer p.l.Unlock()

	txn := p.paths.Txn()
	for _, prefix := range paths {
		if len(prefix) == 0 {
			continue
		}

		// Exceptions aren't stored with the leading ! so strip it
		if strings.HasPrefix(prefix, "!") {
			prefix = strings.TrimPrefix(prefix, "!")
		}

		// We trim any trailing *, but we don't touch whether it is a trailing
		// slash or not since we want to be able to ignore prefixes that fully
		// specify a file
		txn.Delete([]byte(strings.TrimSuffix(prefix, "*")))
	}
	p.paths = txn.Commit()
}
565355
func (r *Role) RemovePaths(paths []string) {
	r.Paths = subtractStrSlices(r.Paths, paths)
}
1235347
func (t *TermsLookup) Path(path string) *TermsLookup {
	t.path = path
	return t
}
510538
func (fs *FS) PrefixPath(path string) string {
	return fs.Prefix + string(fs.PathSeparator()) + path
}
1269021
func makeFullPath(path string) []string {
	parts := stringex.SplitMap(path, "/", func(p string) (string, bool) {
		if p == "" {
			return "", false
		}
		return strings.ToLower(p), true
	})
	return append(etcRoot, parts...)
}
748526
func cleanAndExpandPath(path string) string {
	// Expand initial ~ to OS specific home directory.
	if strings.HasPrefix(path, "~") {
		homeDir := filepath.Dir(defaultHomeDir)
		path = strings.Replace(path, "~", homeDir, 1)
	}

	// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
	// but they variables can still be expanded via POSIX-style $VARIABLE.
	return filepath.Clean(os.ExpandEnv(path))
}
914602
func IsCleanSlashPath(p string) bool {
	if p == "" {
		return false
	}
	if strings.ContainsRune(p, '\\') {
		return false
	}
	if p != path.Clean(p) {
		return false
	}
	if p[0] == '/' || p == ".." || strings.HasPrefix(p, "../") {
		return false
	}
	return true
}
420061
func (b *FileBackend) cleanupLogicalPath(path string) error {
	nodes := strings.Split(path, fmt.Sprintf("%c", os.PathSeparator))
	for i := len(nodes) - 1; i > 0; i-- {
		fullPath := filepath.Join(b.path, filepath.Join(nodes[:i]...))

		dir, err := os.Open(fullPath)
		if err != nil {
			if dir != nil {
				dir.Close()
			}
			if os.IsNotExist(err) {
				return nil
			} else {
				return err
			}
		}

		list, err := dir.Readdir(1)
		dir.Close()
		if err != nil && err != io.EOF {
			return err
		}

		// If we have no entries, it's an empty directory; remove it
		if err == io.EOF || list == nil || len(list) == 0 {
			err = os.Remove(fullPath)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
571356
func hasPathPrefix(s, pathPrefix string) bool {

	s = strings.TrimSuffix(s, "/")
	pathPrefix = strings.TrimSuffix(pathPrefix, "/")

	// Short circuit if s doesn't contain the prefix at all
	if !strings.HasPrefix(s, pathPrefix) {
		return false
	}

	pathPrefixLength := len(pathPrefix)

	if len(s) == pathPrefixLength {
		// Exact match
		return true
	}

	if s[pathPrefixLength:pathPrefixLength+1] == "/" {
		// The next character in s is a path segment boundary
		// Check this instead of normalizing pathPrefix to avoid allocating on every call
		// Example where this check applies: s=/foo/bar and pathPrefix=/foo
		return true
	}

	return false
}
164224
func (s *Store) Prune(ctx context.Context, prefix string) error {
	path := filepath.Join(s.path, filepath.Clean(prefix))
	out.Debug(ctx, "fs.Prune(%s) - %s", prefix, path)
	return os.RemoveAll(path)
}
327109
func SplitPath(path string) []string {
	p := strings.TrimPrefix(path, "/")
	return strings.Split(strings.TrimSuffix(p, "/"), "/")
}
213127
func (p *PathManager) RemovePathPrefix(prefix string) {
	p.l.Lock()
	defer p.l.Unlock()

	// We trim any trailing *, but we don't touch whether it is a trailing
	// slash or not since we want to be able to ignore prefixes that fully
	// specify a file
	p.paths, _ = p.paths.DeletePrefix([]byte(strings.TrimSuffix(prefix, "*")))
}
85293
func normalizePath(ref swspec.Ref, opts *FlattenOpts) (normalizedPath string) {
	if ref.HasFragmentOnly || filepath.IsAbs(ref.String()) {
		normalizedPath = ref.String()
		return
	}

	refURL, _ := url.Parse(ref.String())
	if refURL.Host != "" {
		normalizedPath = ref.String()
		return
	}

	parts := strings.Split(ref.String(), "#")
	parts[0] = filepath.Join(filepath.Dir(opts.BasePath), parts[0])
	normalizedPath = strings.Join(parts, "#")
	return
}