void AppendFileName()

in src/brpc/builtin/common.cpp [147:217]


void AppendFileName(std::string* dir, const std::string& filename) {
    if (dir->empty()) {
        dir->append(filename);
        return;
    }
    const size_t len = filename.size();
    if (len >= 3) {
        if (butil::back_char(*dir) != '/') {
            dir->push_back('/');
        }
        dir->append(filename);
    } else if (len == 1) {
        if (filename[0] != '.') {
            if (butil::back_char(*dir) != '/') {
                dir->push_back('/');
            }
            dir->append(filename);
        }
    } else if (len == 2) {
        if (filename[0] != '.' || filename[1] != '.') {
            if (butil::back_char(*dir) != '/') {
                dir->push_back('/');
            }
            dir->append(filename);
        } else {
            const bool is_abs = (dir->c_str()[0] == '/');
            int npop = 1;
            while (npop > 0) {
                const char* p = dir->c_str() + dir->size() - 1;
                for (; p != dir->c_str() && *p == '/'; --p);
                if (p == dir->c_str()) {
                    dir->clear();
                    break;
                }
                dir->resize(p - dir->c_str() + 1);

                size_t slash_pos = dir->find_last_of('/');
                if (slash_pos == std::string::npos) {
                    --npop;
                    dir->clear();
                    break;
                }
                if (strcmp(dir->data() + slash_pos + 1, ".") != 0) {
                    if (strcmp(dir->data() + slash_pos + 1, "..") == 0) {
                        ++npop;
                    } else {
                        --npop;
                    }
                }
                ssize_t new_pos = (ssize_t)slash_pos - 1;
                for (; new_pos >= 0 && (*dir)[new_pos] == '/'; --new_pos);
                dir->resize(new_pos + 1);
                if (dir->empty()) {
                    break;
                }
            }
            if (dir->empty()) {
                if (is_abs) {
                    dir->push_back('/');
                } else {
                    if (npop > 0) {
                        dir->append("..");
                        for (int i = 1; i < npop; ++i) {
                            dir->append("/..");
                        }
                    }
                }
            }
        }
    } // else len == 0, nothing to do
}