diff --git a/cmd/csearch/csearch.go b/cmd/csearch/csearch.go index 4e12d6ca58..eb1d2e5816 100644 --- a/cmd/csearch/csearch.go +++ b/cmd/csearch/csearch.go @@ -11,11 +11,11 @@ import ( "os" "runtime/pprof" - "github.com/google/codesearch/index" + "github.com/Evengining/codesearch/index" "github.com/google/codesearch/regexp" ) -var usageMessage = `usage: csearch [-c] [-f fileregexp] [-h] [-i] [-l] [-n] regexp +var usageMessage = `usage: csearch [-c] [-f fileregexp] [-h] [-i] [-l] [-n] regexp [filter for regex] Csearch behaves like grep over all indexed files, searching for regexp, an RE2 (nearly PCRE) regular expression. @@ -66,7 +66,7 @@ func Main() { flag.Parse() args := flag.Args() - if len(args) != 1 { + if len(args) != 2 { usage() } @@ -96,7 +96,16 @@ func Main() { log.Fatal(err) } } + filter := "(?m)" + args[1] + if *iFlag { + filter = "(?i)" + filter + } + filterRe, err := regexp.Compile(filter) + if err != nil { + log.Fatal(err) + } q := index.RegexpQuery(re.Syntax) + filterQuery := index.RegexpQuery(filterRe.Syntax) if *verboseFlag { log.Printf("query: %s\n", q) } @@ -105,9 +114,9 @@ func Main() { ix.Verbose = *verboseFlag var post []uint32 if *bruteFlag { - post = ix.PostingQuery(&index.Query{Op: index.QAll}) + post = ix.PostingQuery(&index.Query{Op: index.QAll}, filterQuery) } else { - post = ix.PostingQuery(q) + post = ix.PostingQuery(q, filterQuery) } if *verboseFlag { log.Printf("post query identified %d possible files\n", len(post)) diff --git a/index/read.go b/index/read.go index 72ee834418..67bd1027ed 100644 --- a/index/read.go +++ b/index/read.go @@ -330,11 +330,25 @@ func (ix *Index) postingOr(list []uint32, trigram uint32, restrict []uint32) []u return x } -func (ix *Index) PostingQuery(q *Query) []uint32 { - return ix.postingQuery(q, nil) +func (ix *Index) PostingQuery(q *Query, filter *Query) []uint32 { + return ix.postingQuery(q, filter, nil) } -func (ix *Index) postingQuery(q *Query, restrict []uint32) (ret []uint32) { +func (ix *Index) filterPostingQuery(q *Query, list []uint32) (ret []uint32) { + var finds = ix.postingQuery(q, nil, nil) + var findsIds = make([]uint32, 0, len(finds)) + for _, id := range finds { + for _, listId := range list { + if id != listId { + continue + } + findsIds = append(findsIds, id) + } + } + return findsIds +} + +func (ix *Index) postingQuery(q *Query, filter *Query, restrict []uint32) (ret []uint32) { var list []uint32 switch q.Op { case QNone: @@ -347,7 +361,9 @@ func (ix *Index) postingQuery(q *Query, restrict []uint32) (ret []uint32) { for i := range list { list[i] = uint32(i) } - return list + if filter != nil { + list = ix.filterPostingQuery(filter, list) + } case QAnd: for _, t := range q.Trigram { tri := uint32(t[0])<<16 | uint32(t[1])<<8 | uint32(t[2]) @@ -364,11 +380,14 @@ func (ix *Index) postingQuery(q *Query, restrict []uint32) (ret []uint32) { if list == nil { list = restrict } - list = ix.postingQuery(sub, list) + list = ix.postingQuery(sub, nil, list) if len(list) == 0 { return nil } } + if filter != nil { + list = ix.filterPostingQuery(filter, list) + } case QOr: for _, t := range q.Trigram { tri := uint32(t[0])<<16 | uint32(t[1])<<8 | uint32(t[2]) @@ -379,9 +398,12 @@ func (ix *Index) postingQuery(q *Query, restrict []uint32) (ret []uint32) { } } for _, sub := range q.Sub { - list1 := ix.postingQuery(sub, restrict) + list1 := ix.postingQuery(sub, nil, restrict) list = mergeOr(list, list1) } + if filter != nil { + list = ix.filterPostingQuery(filter, list) + } } return list }