X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=tgt.go;h=a8525ed426aa2aa374959b18a8ca3a1e507f2753;hb=HEAD;hp=8e454f2c94a884dc85a826e47ba570eaf705c362;hpb=af40222f5a3e6fa82207f7ba31c338eb44566ba3;p=goredo.git diff --git a/tgt.go b/tgt.go index 8e454f2..a8525ed 100644 --- a/tgt.go +++ b/tgt.go @@ -1,11 +1,30 @@ +// goredo -- djb's redo implementation on pure Go +// Copyright (C) 2020-2024 Sergey Matveev +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + package main import ( "path" "path/filepath" + "sync" ) -var TgtCache = make(map[string]*Tgt) +var ( + TgtCache = make(map[string]*Tgt) + TgtCacheM sync.RWMutex +) func mustAbs(pth string) string { pth, err := filepath.Abs(pth) @@ -27,45 +46,44 @@ func cwdMustRel(paths ...string) string { return mustRel(Cwd, path.Join(paths...)) } +func pathSplit(a string) (h, t string) { + h, t = path.Split(a) + if len(h) > 1 { + h = h[:len(h)-1] + } + return +} + type Tgt struct { - // a/h/t resemble zsh'es :a, :h, :t modifiers a string // absolute path - h string // head of the path, directory - t string // tail of the path, only name rel string // relative to Cwd dep string // path to dependency file } func NewTgt(tgt string) *Tgt { a := mustAbs(tgt) - if TgtCache != nil { - if t := TgtCache[a]; t != nil { - return t - } + TgtCacheM.RLock() + cached := TgtCache[a] + TgtCacheM.RUnlock() + if cached != nil { + return cached } - t := Tgt{a: a} - t.h, t.t = path.Split(t.a) - if len(t.h) > 1 { - t.h = t.h[:len(t.h)-1] + h, t := pathSplit(a) + res := Tgt{ + a: a, + rel: mustRel(Cwd, a), + dep: path.Join(h, RedoDir, t+DepSuffix), } - t.rel = mustRel(Cwd, t.a) - if TgtCache != nil { - TgtCache[a] = &t - } - return &t + TgtCacheM.Lock() + TgtCache[a] = &res + TgtCacheM.Unlock() + return &res } func (tgt *Tgt) String() string { return tgt.rel } -func (tgt *Tgt) Dep() string { - if tgt.dep == "" { - tgt.dep = path.Join(tgt.h, RedoDir, tgt.t+DepSuffix) - } - return tgt.dep -} - func (tgt *Tgt) RelTo(cwd string) string { return mustRel(cwd, tgt.a) }