// Walk returns a new Walker rooted at root on the FileSystem fs.
189227
func Walk(ctx context.Context, root string, fs FileSystem) *Walker {
	info, err := fs.Lstat(ctx, root)
	return &Walker{
		fs:    fs,
		ctx:   ctx,
		stack: []item{{root, info, err}},
	}
}
1351634
func (n *ConstList) Walk(v walker.Visitor) {
	if v.EnterNode(n) == false {
		return
	}

	if n.Consts != nil {
		v.EnterChildList("Consts", n)
		for _, nn := range n.Consts {
			if nn != nil {
				nn.Walk(v)
			}
		}
		v.LeaveChildList("Consts", n)
	}

	v.LeaveNode(n)
}
775680
func (n *If) Walk(v walker.Visitor) {
	if v.EnterNode(n) == false {
		return
	}

	if n.Cond != nil {
		v.EnterChildNode("Cond", n)
		n.Cond.Walk(v)
		v.LeaveChildNode("Cond", n)
	}

	if n.Stmt != nil {
		v.EnterChildNode("Stmt", n)
		n.Stmt.Walk(v)
		v.LeaveChildNode("Stmt", n)
	}

	if n.ElseIf != nil {
		v.EnterChildList("ElseIf", n)
		for _, nn := range n.ElseIf {
			if nn != nil {
				nn.Walk(v)
			}
		}
		v.LeaveChildList("ElseIf", n)
	}

	if n.Else != nil {
		v.EnterChildNode("Else", n)
		n.Else.Walk(v)
		v.LeaveChildNode("Else", n)
	}

	v.LeaveNode(n)
}
118753
func (c *cachedFS) Walk(ctx context.Context, path string, fn WalkFn) error {
	return c.src.Walk(ctx, path, fn)
}
1231562
func (w *Walker) Walk(root string, walkFn filepath.WalkFunc) error {
	w.jobs = make(chan string, BufferSize)
	w.walkFunc = walkFn

	info, err := os.Lstat(root)
	err = w.walkFunc(root, info, err)
	if err != nil {
		return err
	}
	if !info.IsDir() {
		return ErrNotDir
	}

	// spawn workers
	for n := 1; n <= NumWorkers; n++ {
		go w.worker()
	}
	w.addJob(root) // add root path as a first job
	w.wg.Wait()    // wait till all paths are processed
	close(w.jobs)  // signal workers to close

	return nil
}
551978
func (w *walker) walk(path string, i1, i2 os.FileInfo) (err error) {
	// Register these nodes with the return trees, unless we're still at the
	// (already-created) roots:
	if path != "/" {
		if err := walkchunk(path, i1, w.dir1, w.root1); err != nil {
			return err
		}
		if err := walkchunk(path, i2, w.dir2, w.root2); err != nil {
			return err
		}
	}

	is1Dir := i1 != nil && i1.IsDir()
	is2Dir := i2 != nil && i2.IsDir()

	sameDevice := false
	if i1 != nil && i2 != nil {
		si1 := i1.Sys().(*syscall.Stat_t)
		si2 := i2.Sys().(*syscall.Stat_t)
		if si1.Dev == si2.Dev {
			sameDevice = true
		}
	}

	// If these files are both non-existent, or leaves (non-dirs), we are done.
	if !is1Dir && !is2Dir {
		return nil
	}

	// Fetch the names of all the files contained in both directories being walked:
	var names1, names2 []nameIno
	if is1Dir {
		names1, err = readdirnames(filepath.Join(w.dir1, path)) // getdents(2): fs access
		if err != nil {
			return err
		}
	}
	if is2Dir {
		names2, err = readdirnames(filepath.Join(w.dir2, path)) // getdents(2): fs access
		if err != nil {
			return err
		}
	}

	// We have lists of the files contained in both parallel directories, sorted
	// in the same order. Walk them in parallel, generating a unique merged list
	// of all items present in either or both directories.
	var names []string
	ix1 := 0
	ix2 := 0

	for {
		if ix1 >= len(names1) {
			break
		}
		if ix2 >= len(names2) {
			break
		}

		ni1 := names1[ix1]
		ni2 := names2[ix2]

		switch bytes.Compare([]byte(ni1.name), []byte(ni2.name)) {
		case -1: // ni1 < ni2 -- advance ni1
			// we will not encounter ni1 in names2
			names = append(names, ni1.name)
			ix1++
		case 0: // ni1 == ni2
			if ni1.ino != ni2.ino || !sameDevice {
				names = append(names, ni1.name)
			}
			ix1++
			ix2++
		case 1: // ni1 > ni2 -- advance ni2
			// we will not encounter ni2 in names1
			names = append(names, ni2.name)
			ix2++
		}
	}
	for ix1 < len(names1) {
		names = append(names, names1[ix1].name)
		ix1++
	}
	for ix2 < len(names2) {
		names = append(names, names2[ix2].name)
		ix2++
	}

	// For each of the names present in either or both of the directories being
	// iterated, stat the name under each root, and recurse the pair of them:
	for _, name := range names {
		fname := filepath.Join(path, name)
		var cInfo1, cInfo2 os.FileInfo
		if is1Dir {
			cInfo1, err = os.Lstat(filepath.Join(w.dir1, fname)) // lstat(2): fs access
			if err != nil && !os.IsNotExist(err) {
				return err
			}
		}
		if is2Dir {
			cInfo2, err = os.Lstat(filepath.Join(w.dir2, fname)) // lstat(2): fs access
			if err != nil && !os.IsNotExist(err) {
				return err
			}
		}
		if err = w.walk(fname, cInfo1, cInfo2); err != nil {
			return err
		}
	}
	return nil
}
806114
func (l Local) Walk(_ context.Context, path string, fn WalkFn) error {
	return filepath.Walk(l.fullPath(path), func(path string, f os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if !f.IsDir() {
			path = strings.TrimPrefix(path, string(l))
			return fn(path)
		}
		return nil
	})
}
565460
func walk(root string, fsView common.FilesystemView, c chan<- *walkItem) {
	// TODO(maruel): Walk() sorts the file names list, which is not needed here
	// and slows things down. Options:
	// #1 Use os.File.Readdir() directly. It's in the stdlib and works fine, but
	//    it's not the most efficient implementation. On posix it does a lstat()
	//    call, on Windows it does a Win32FileAttributeData.
	// #2 Use raw syscalls.
	//   - On POSIX, use syscall.ReadDirent(). See src/os/dir_unix.go.
	//   - On Windows, use syscall.FindFirstFile(), syscall.FindNextFile(),
	//     syscall.FindClose() directly. See src/os/file_windows.go. For odd
	//     reasons, Windows does not have a batched version to reduce the number
	//     of kernel calls. It's as if they didn't care about performance.
	//
	// In practice, #2 may not be needed, the performance of #1 may be good
	// enough relative to the other performance costs. This needs to be perf
	// tested at 100k+ files scale on Windows and OSX.
	//
	// TODO(maruel): Cache directory enumeration. In particular cases (Chromium),
	// the same directory may be enumerated multiple times. Caching the content
	// may be worth. This needs to be perf tested.

	total := 0
	end := tracer.Span(root, "walk:"+filepath.Base(root), nil)
	defer func() { end(tracer.Args{"root": root, "total": total}) }()

	var walkWithLinks func(string, common.FilesystemView) filepath.WalkFunc

	walkWithLinks = func(dir string, view common.FilesystemView) filepath.WalkFunc {
		return func(path string, info os.FileInfo, err error) error {
			total++

			if err != nil {
				return fmt.Errorf("walk(%q): %v", path, err)
			}
			relPath, err := view.RelativePath(path)
			if err != nil {
				return fmt.Errorf("walk(%q): %v", path, err)
			}
			if relPath == "" { // empty string indicates skip.
				return common.WalkFuncSkipFile(info)
			}

			// Follow symlinks in the tree, treating links that point outside the as if they
			// were ordinary files or directories.
			//
			// The rule about symlinks outside the build tree is for the benefit of use-cases
			// in which not all objects are available in a canonical directory (e.g., when one
			// wishes to isolate build directory artifacts along with dynamically created files).
			mode := info.Mode()
			if mode&os.ModeSymlink == os.ModeSymlink {
				l, err := filepath.EvalSymlinks(path)
				if err != nil {
					return fmt.Errorf("EvalSymlinks(%s): %s", path, err)
				}
				info, err = os.Stat(l)
				if err != nil {
					return fmt.Errorf("Stat(%s): %s", l, err)
				}
				if strings.HasPrefix(l, dir) {
					c <- &walkItem{fullPath: l[len(dir)+1:], relPath: relPath, info: info, inTreeSymlink: true}
					return nil
				}

				if info.IsDir() {
					linkedView := view.NewSymlinkedView(relPath, l)
					return filepath.Walk(l, walkWithLinks(l, linkedView))
				} else {
					c <- &walkItem{fullPath: l, relPath: relPath, info: info}
				}
				return nil
			}

			if !info.IsDir() {
				c <- &walkItem{fullPath: path, relPath: relPath, info: info}
			}
			return nil
		}
	}

	if err := filepath.Walk(root, walkWithLinks(root, fsView)); err != nil {
		// No point continuing if an error occurred during walk.
		log.Fatalf("Unable to walk %q: %v", root, err)
	}
}
417558
func walk(osPathname string, dirent *Dirent, options *Options) error {
	err := options.Callback(osPathname, dirent)
	if err != nil {
		if err == filepath.SkipDir {
			return err
		}
		err = errCallback(err.Error()) // wrap potential errors returned by callback
		if action := options.ErrorCallback(osPathname, err); action == SkipNode {
			return nil
		}
		return err
	}

	// On some platforms, an entry can have more than one mode type bit set.
	// For instance, it could have both the symlink bit and the directory bit
	// set indicating it's a symlink to a directory.
	if dirent.IsSymlink() {
		if !options.FollowSymbolicLinks {
			return nil
		}
		skip, err := symlinkDirHelper(osPathname, dirent, options)
		if err != nil || skip {
			return err
		}
	}

	if !dirent.IsDir() {
		return nil
	}

	// If get here, then specified pathname refers to a directory.
	deChildren, err := ReadDirents(osPathname, options.ScratchBuffer)
	if err != nil {
		if action := options.ErrorCallback(osPathname, err); action == SkipNode {
			return nil
		}
		return err
	}

	if !options.Unsorted {
		sort.Sort(deChildren) // sort children entries unless upstream says to leave unsorted
	}

	for _, deChild := range deChildren {
		osChildname := filepath.Join(osPathname, deChild.name)
		err = walk(osChildname, deChild, options)
		if err != nil {
			if err != filepath.SkipDir {
				return err
			}
			// If received skipdir on a directory, stop processing that
			// directory, but continue to its siblings. If received skipdir on a
			// non-directory, stop processing remaining siblings.
			if deChild.IsSymlink() {
				var skip bool
				if skip, err = symlinkDirHelper(osChildname, deChild, options); err != nil {
					return err
				}
				if skip {
					continue
				}
			}
			if !deChild.IsDir() {
				// If not directory, return immediately, thus skipping remainder
				// of siblings.
				return nil
			}
		}
	}

	if options.PostChildrenCallback == nil {
		return nil
	}

	err = options.PostChildrenCallback(osPathname, dirent)
	if err == nil || err == filepath.SkipDir {
		return err
	}

	err = errCallback(err.Error()) // wrap potential errors returned by callback
	if action := options.ErrorCallback(osPathname, err); action == SkipNode {
		return nil
	}
	return err
}
667707
func (n *Use) Walk(v walker.Visitor) {
	if v.EnterNode(n) == false {
		return
	}

	if n.UseType != nil {
		v.EnterChildNode("UseType", n)
		n.UseType.Walk(v)
		v.LeaveChildNode("UseType", n)
	}

	if n.Use != nil {
		v.EnterChildNode("Use", n)
		n.Use.Walk(v)
		v.LeaveChildNode("Use", n)
	}

	if n.Alias != nil {
		v.EnterChildNode("Alias", n)
		n.Alias.Walk(v)
		v.LeaveChildNode("Alias", n)
	}

	v.LeaveNode(n)
}
517541
func (b *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapshots.Info) error) error {
	ctx, t, err := b.ms.TransactionContext(ctx, false)
	if err != nil {
		return err
	}
	defer t.Rollback()
	return storage.WalkInfo(ctx, fn)
}
606862
func (l *lcowfs) Walk(root string, walkFn filepath.WalkFunc) error {
	info, err := l.Lstat(root)
	if err != nil {
		err = walkFn(root, nil, err)
	} else {
		err = l.walk(root, info, walkFn)
	}
	if err == filepath.SkipDir {
		return nil
	}
	return err
}
1183493
func (n *New) Walk(v walker.Visitor) {
	if v.EnterNode(n) == false {
		return
	}

	if n.Class != nil {
		v.EnterChildNode("Class", n)
		n.Class.Walk(v)
		v.LeaveChildNode("Class", n)
	}

	if n.ArgumentList != nil {
		v.EnterChildNode("ArgumentList", n)
		n.ArgumentList.Walk(v)
		v.LeaveChildNode("ArgumentList", n)
	}

	v.LeaveNode(n)
}
479797
func (t *trg) walk(p string, fn func(os.FileInfo) error) error {
	fp, err := os.Open(p)
	if err != nil {
		return err
	}
	ls, err := fp.Readdir(0)
	fp.Close()
	if err != nil {
		return err
	}
	for i := range ls {
		if err := fn(ls[i]); err != nil {
			return err
		}
	}
	return nil
}
286999
func (clnt *Clnt) Walk(fid *Fid, newfid *Fid, wnames []string) ([]Qid, error) {
	tc := clnt.NewFcall()
	err := PackTwalk(tc, fid.Fid, newfid.Fid, wnames)
	if err != nil {
		return nil, err
	}

	rc, err := clnt.Rpc(tc)
	if err != nil {
		return nil, err
	}

	newfid.walked = true
	return rc.Wqid, nil
}
217228
func (n *AltFor) Walk(v walker.Visitor) {
	if v.EnterNode(n) == false {
		return
	}

	if n.Init != nil {
		v.EnterChildList("Init", n)
		for _, nn := range n.Init {
			if nn != nil {
				nn.Walk(v)
			}
		}
		v.LeaveChildList("Init", n)
	}

	if n.Cond != nil {
		v.EnterChildList("Cond", n)
		for _, nn := range n.Cond {
			if nn != nil {
				nn.Walk(v)
			}
		}
		v.LeaveChildList("Cond", n)
	}

	if n.Loop != nil {
		v.EnterChildList("Loop", n)
		for _, nn := range n.Loop {
			if nn != nil {
				nn.Walk(v)
			}
		}
		v.LeaveChildList("Loop", n)
	}

	if n.Stmt != nil {
		v.EnterChildNode("Stmt", n)
		n.Stmt.Walk(v)
		v.LeaveChildNode("Stmt", n)
	}

	v.LeaveNode(n)
}
446906
func Walk(root string) <-chan WalkItem {
	// probably more efficient since wait only when chan is full
	iterChannel := make(chan WalkItem, chanBuffSize)
	dirsAlreadyProcessed := make(map[string]bool)
	dirsToProcess := []string{root}
	go func() {
		for len(dirsToProcess) > 0 {
			dirs, files := []os.FileInfo{}, []os.FileInfo{}
			dirpath := NormalizePath(dirsToProcess[len(dirsToProcess)-1])
			dirsToProcess = dirsToProcess[:len(dirsToProcess)-1]
			if _, ok := dirsAlreadyProcessed[dirpath]; !ok {
				dirsAlreadyProcessed[dirpath] = true
				filesInfo, err := ioutil.ReadDir(NormalizePath(dirpath))
				if err != nil {
					log.Errorf("Error reading directory (%s): %s\n", err.Error(), dirpath)
				} else {
					for _, fileInfo := range filesInfo {
						switch {
						case fileInfo.Mode().IsDir():
							dirs = append(dirs, fileInfo)
							dirsToProcess = append(dirsToProcess, filepath.Join(dirpath, fileInfo.Name()))
						case fileInfo.Mode().IsRegular():
							files = append(files, fileInfo)
						case fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink:
							var pointerFI os.FileInfo
							sympath := NormalizePath(filepath.Join(dirpath, fileInfo.Name()))
							pointerFI, err = os.Stat(sympath)
							if err != nil {
								log.Errorf("Error reading symlink (%s): %s\n", err.Error(), sympath)
							} else {
								switch {
								case pointerFI.Mode().IsDir():
									dirs = append(dirs, fileInfo)
									dirsToProcess = append(dirsToProcess, sympath)
								case pointerFI.Mode().IsRegular():
									files = append(files, fileInfo)
								}
							}
						}
					}
				}
				iterChannel <- WalkItem{dirpath, dirs, files, err}
			}
		}
		close(iterChannel)
	}()
	return iterChannel
}