func main() { var g regexp.Grep g.AddFlags() g.Stdout = os.Stdout g.Stderr = os.Stderr flag.Usage = usage flag.Parse() args := flag.Args() if len(args) == 0 { flag.Usage() } if *cpuProfile != "" { f, err := os.Create(*cpuProfile) if err != nil { log.Fatal(err) } defer f.Close() pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } pat := "(?m)" + args[0] if *iflag { pat = "(?i)" + pat } re, err := regexp.Compile(pat) if err != nil { log.Fatal(err) } g.Regexp = re if len(args) == 1 { g.Reader(os.Stdin, "<standard input>") } else { for _, arg := range args[1:] { g.File(arg) } } if !g.Match { os.Exit(1) } }
func searchPattern(idx *index.Index, pattern string, options *SearchOptions, w flushWriter) ([]*SearchResult, error) { var results []*SearchResult var stdout, stderr bytes.Buffer bStdout := bufio.NewWriter(&stdout) bStderr := bufio.NewWriter(&stderr) grep := regexp.Grep{ Stdout: bStdout, Stderr: bStderr, N: true, } // grep.AddFlags() re, err := regexp.Compile(pattern) if err != nil { return nil, err } grep.Regexp = re q := index.RegexpQuery(re.Syntax) var post []uint32 post = idx.PostingQuery(q) w.Write([]byte("\"results\": [\n")) // This is needed to check whether we need to print a "," to respect JSON // syntax isFirst := true for _, fileid := range post { name := idx.Name(fileid) grep.File(name) bStdout.Flush() bStderr.Flush() for { line, err := stdout.ReadString('\n') if err == io.EOF { break } else if err != nil { log.Printf("Error from ReadString: %s", err.Error()) return nil, err } // log.Printf("LINE: %s", line) fields := strings.SplitN(line, ":", 3) ln, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { log.Printf("Error converting line number: %s", err.Error()) return nil, err } sr := &SearchResult{ Filename: fields[0], Line: ln, Match: html.EscapeString(fields[2]), } results = append(results, sr) jr, err := json.Marshal(sr) if err != nil { log.Printf("JSON error: %s", err.Error()) return nil, err } if !isFirst { w.Write([]byte(",\n")) } else { isFirst = false } w.Write(jr) } } w.Write([]byte("]\n")) return results, nil }
func main() { var ignorePatterns []*regexp.Regexp flag.Usage = usage flag.Var(&iFlag, "ignore", "Ignore filenames matching PATTERN") flag.Parse() args := flag.Args() if *listFlag || *listIgnoreFlag { ix := index.Open(index.File()) var what []string if *listFlag { what = ix.Paths() } else { what = ix.Ignores() } for _, arg := range what { fmt.Printf("%s\n", arg) } return } // culo if *listIgnoreFlag { } if *cpuProfile != "" { f, err := os.Create(*cpuProfile) if err != nil { log.Fatal(err) } defer f.Close() pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } if *resetFlag && len(args) == 0 { os.Remove(index.File()) return } if len(args) == 0 { ix := index.Open(index.File()) for _, arg := range ix.Paths() { args = append(args, arg) } } if len(iFlag) > 0 { for _, pattern := range iFlag { ire, err := regexp.Compile(pattern) if err != nil { log.Fatal(err) } ignorePatterns = append(ignorePatterns, ire) } } // Translate paths to absolute paths so that we can // generate the file list in sorted order. for i, arg := range args { a, err := filepath.Abs(arg) if err != nil { log.Printf("%s: %s", arg, err) args[i] = "" continue } args[i] = a } sort.Strings(args) for len(args) > 0 && args[0] == "" { args = args[1:] } master := index.File() if _, err := os.Stat(master); err != nil { // Does not exist. *resetFlag = true } file := master if !*resetFlag { file += "~" } ix := index.Create(file) ix.Verbose = *verboseFlag ix.AddPaths(args) ix.AddIgnores(iFlag) for _, arg := range args { log.Printf("index %s", arg) filepath.Walk(arg, func(path string, info os.FileInfo, err error) error { if _, elem := filepath.Split(path); elem != "" { // Skip various temporary or "hidden" files or directories. if elem[0] == '.' || elem[0] == '#' || elem[0] == '~' || elem[len(elem)-1] == '~' { if info.IsDir() { return filepath.SkipDir } return nil } } if len(ignorePatterns) > 0 { for _, ip := range ignorePatterns { if ip.MatchString(path, true, true) > 0 { log.Printf("Ignoring %s\n", path) return nil } } } if err != nil { log.Printf("%s: %s", path, err) return nil } if info != nil && info.Mode()&os.ModeType == 0 { ix.AddFile(path) } return nil }) } log.Printf("flush index") ix.Flush() if !*resetFlag { log.Printf("merge %s %s", master, file) index.Merge(file+"~", master, file) os.Remove(file) os.Rename(file+"~", master) } log.Printf("done") return }