func SystemRomPath(fileName string) (string, error) {
	var (
		currDir = "roms"
		userDir = path.Join(DefaultUserDir, "roms")
		srcDir  = path.Join(srcDir, "roms")
	)
	var paths []string
	paths = append(paths, currDir, userDir, srcDir)
	appendCustomSearchPaths(&paths)
	return searchForValidPath(paths, fileName)
}
Returns a valid path for the 48k system ROM,
or the original filename if the search did not find anything.

An error is returned if the search could not proceed.

The search is performed in this order:
1. ./roms/
2. $HOME/.config/gospeccy/roms/
3. $GOPATH/src/github.com/remogatto/gospeccy/roms/
4. Custom search paths
package spectrum
import (
	"errors"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
)
var DefaultUserDir = path.Join(os.Getenv("HOME"), ".config", "gospeccy")
var srcDir string
func init() {
	gopaths := os.Getenv("GOPATH")
	gopath0 := strings.Split(gopaths, string(os.PathListSeparator))[0]
	srcDir = path.Join(gopath0, "src", "github.com", "remogatto", "gospeccy")
}
var customSearchPaths []string
var downloadPath string
var mutex sync.RWMutex
func AddCustomSearchPath(path string) {
	mutex.Lock()
	customSearchPaths = append(customSearchPaths, path)
	mutex.Unlock()
}
func DownloadPath() string {
	mutex.RLock()
	p := downloadPath
	mutex.RUnlock()
	if p == "" {
		p = path.Join(DefaultUserDir, "snapshots")
	}
	return p
}
func SetDownloadPath(path string) {
	mutex.Lock()
	downloadPath = path
	mutex.Unlock()
}
func searchForValidPath(paths []string, fileName string) (string, error) {
	for _, dir := range paths {
		if _, err := os.Lstat(dir); err == nil {
			_, err = filepath.EvalSymlinks(dir)
			if err != nil {
				return "", errors.New("path \"" + dir + "\" contains an invalid symbolic link")
			}
		}
		fullPath := path.Join(dir, fileName)
		if _, err := os.Stat(fullPath); err == nil {
			return fullPath, nil
		}
	}
	return fileName, nil
}
func appendCustomSearchPaths(paths *[]string) {
	mutex.RLock()
	*paths = append(*paths, customSearchPaths...)
	mutex.RUnlock()
}
func ProgramPath(fileName string) (string, error) {
	var (
		currDir = "programs"
		userDir = path.Join(DefaultUserDir, "programs")
		srcDir  = path.Join(srcDir, "programs")
	)
	var paths []string
	paths = append(paths, currDir, userDir, srcDir)
	appendCustomSearchPaths(&paths)
	paths = append(paths, DownloadPath())
	return searchForValidPath(paths, fileName)
}