int Walker::next()

in fs/path.cpp [297:343]


    int Walker::next()
    {
    again:
        if (m_path_len == 0) return -1;
        std::string_view path(m_path_buffer, m_path_len);
        if (path.back() != '/')
        {
            auto m = path.rfind('/');
            if (m != path.npos) {
              auto len0 = path.length();
              path_pop_back(len0 - m - 1);
              m_stack.top()->next();
            }
        }

        dirent* entry;
        string_view name;
        while(true)
        {
            entry = m_stack.top()->get();
            if (entry) {
              name = entry->d_name;
              if (!is_dots(name)) break;
              if (m_stack.top()->next() == 1) continue;
            }
            m_stack.pop();
            if (m_stack.empty())
            {
                m_path_len = 0;
                return -1; // finished walking
            }
            assert(m_path_buffer[m_path_len - 1] == '/');
            path_pop_back(1);
            goto again;
        }

        path_push_back(name);
        int ret = is_dir(entry);
        if (ret < 0) {
            return -1;  // fail
        } else if (ret == 1) {
            enter_dir();
            path_push_back("/");
            goto again;
        } /* else if (ret == 0) */
        return 0;   // file
    }