server/pkg/gendocs/util.go

Summary

Maintainability
A
3 hrs
Test Coverage
package gendocs

import (
    "os"
    "path/filepath"
    "strings"
    "unicode/utf8"
)

func SplitFilepath(path string) (result []string) {
    path = filepath.FromSlash(path)
    separator := os.PathSeparator

    idx := 0
    if separator == '\\' {
        // if the separator is '\\', then we can just split...
        result = strings.Split(path, string(separator))
        idx = len(result)
    } else {
        // otherwise, we need to be careful of situations where the separator was escaped
        cnt := strings.Count(path, string(separator))
        if cnt == 0 {
            return []string{path}
        }

        result = make([]string, cnt+1)
        pathlen := len(path)
        separatorLen := utf8.RuneLen(separator)
        emptyEnd := false
        for start := 0; start < pathlen; {
            end := indexRuneWithEscaping(path[start:], separator)
            if end == -1 {
                emptyEnd = false
                end = pathlen
            } else {
                emptyEnd = true
                end += start
            }
            result[idx] = path[start:end]
            start = end + separatorLen
            idx++
        }

        // If the last rune is a path separator, we need to append an empty string to
        // represent the last, empty path component. By default, the strings from
        // make([]string, ...) will be empty, so we just need to increment the count
        if emptyEnd {
            idx++
        }
    }

    return result[:idx]
}

// Find the first index of a rune in a string,
// ignoring any times the rune is escaped using "\".
func indexRuneWithEscaping(s string, r rune) int {
    end := strings.IndexRune(s, r)
    if end == -1 {
        return -1
    }
    if end > 0 && s[end-1] == '\\' {
        start := end + utf8.RuneLen(r)
        end = indexRuneWithEscaping(s[start:], r)
        if end != -1 {
            end += start
        }
    }
    return end
}